Reputation: 871
I'm trying to run flex on a ScrollView
, and as long as the ScrollView has flex: 1
the scroll inside does not work.
here is the expo fiddle (that you can run this code and play with)
https://snack.expo.io/SySerKNp-
note that if you remove the flex: 1
from the ScrollView
it does let scroll but then you lose the flex power ( the ability to let the red container down to push up the upper box (the ScrollView) ) so I must have a flex there.
p.s - I'm working only on android, and I haven't tested it on iPhone( I don't mind the result there )
any idea what am I missing ? why the ScrollView
won't function right when it has a flex: 1
?
thanks !
Upvotes: 43
Views: 45785
Reputation: 124
flex:1
equals to flexGrow:1 flexShrink:1 flexBasis:0
;
flexGrow:1
equals to flexGrow:1 flexShrink:0 (default value) flexBasis:0
.
So setting flex:1
makes ScrollView content shrink to its parent and so unscrollable.
Upvotes: 0
Reputation: 8591
The best thing to do is to wrap your ScrollView in a View and control that view with flex, your scroll view will follow.
This is a little example
<View style={{flex: 1, flexDirection: 'column',}}>
<View style={{flex:5, backgroundColor : 'green' }}>
<ScrollView style={{margin:50, backgroundColor : 'pink' }}>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
</ScrollView>
</View>
<View style={{flex:1, backgroundColor : 'blue' }}>
<Text> Hello Static View </Text>
</View>
</View>
Upvotes: 5
Reputation: 21
Try this one it will 100% solve your problem
import React, { Component } from 'react';
import { AppRegistry, View,ScrollView } from 'react-native';
export default class AlignItemsBasics extends Component {
render() {
return (
// Try setting `alignItems` to 'flex-start'
// Try setting `justifyContent` to `flex-end`.
// Try setting `flexDirection` to `row`.
<View style={{ flex: 1,flexDirection: 'column' }}>
<View style={{ height: 50, backgroundColor: 'powderblue'}} />
<View style={{ flex: 1, backgroundColor: 'skyblue'}} >
<ScrollView>
<View style={{ flexDirection: 'column' , minHeight: 'fit-content'}} >
<View style={{ height:150, backgroundColor: 'red'}} />
<View style={{ minHeight: 'fit-content', backgroundColor: '#fe3222' }} />
<View style={{ height:150, backgroundColor: '#fff222'}} />
<View style={{ height:150, backgroundColor: '#555222'}} />
</View>
</ScrollView>
</View>
</View>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
Upvotes: 1
Reputation: 3131
Try using flexGrow: 1 instead of flex: 1 in scrollView content container style as follows.
<ScrollView contentContainerStyle={{ flexGrow: 1, borderColor: 'green', borderWidth: 5 }}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</ScrollView>
https://snack.expo.io/HkkEVoh6Z
Upvotes: 134
Reputation: 71
This answer has already been provided how to do it.
But here's an explanation why you cannot do by your method. The styles given in contentContainerStyle
is
applied to the scroll view content container which wraps all of the child views.
So when you apply flex: 1
to contentContainer
it takes full height of ScrollView
whose height is also flex: 1
as its parent View
.
You can also simulate -
the ability to let the red container down to push up the upper box
by adding a parent to ScrollView
and apply style in the parent
<View style={styles.root}>
<View style={{ flex: 1, borderColor: 'green', borderWidth: 5 }}>
<ScrollView>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</ScrollView>
</View>
<View style={{ height: this.state.height, backgroundColor: 'red' }}>
<TouchableOpacity onPress={() => this.setState({ height: this.state.height + 10 })}>
<Text>Click</Text>
</TouchableOpacity>
</View>
</View>
Upvotes: 4
Reputation: 9978
I believe your problem is that you are telling the ScrollView to occupy all available space with flex=1 but the thing is that ScrollView works differently. It automatically renders all its children so it does work different with flex. That is the difference against a normal ListView or FlatList which have better performance.
I believe this snack solves that issue: https://snack.expo.io/SkxN9GOT-
Basically, I am getting the height of the device and setting the ScrollView with a fixed height, based on (screenHeight - the current height of the red box).
Upvotes: 15