I've been making Layouts for Screens in React Native with Flexbox for a while now and hadn't run into any trouble until today when I had to make this very simple layout:
I want the content section to be 3 times bigger than the Header and the Footer, so naturally I set the flex to 1 (header), 3 (content), 1 (footer).
No matter what, the content remains as if it has flex: 1
.
The only way I could control the layout the way I wanted was to leave content's flex: 1
and set both footer and header to flex: 0.33
.
I suspect it might have something to do with ScrollView's contentContainerStyle prop which I set to flexGrow: 1, flexShrink: 1
.
Here's a minimal example which reproduces this.
Update 2:
I've been pointed out that I shouldn't be using a ListView wrapped inside a ScrollView since the following can happen:
It might lead to some weird behaviors like onEndReached
firing continuously.
Wrapping the ListView inside the ScrollView makes the parent scroll action dominate the child scroll action which leads only ScrollView to scroll.
Okay, I'm not sure why this works, but found the solution after hours of trying:
After the step mentioned in Update 1, I added the following style flexGrow: 0
to the FlatList inside the ScrollView and the content became centered and decreasing the content's size until it becomes scrollable works perfectly as well.
Basically this is the resulting code:
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<Text>HEADER</Text>
</View>
<View style={{ flex: 6 }}> // Change this to affect ScrollView size
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
<FlatList
data={listItems}
renderItem={Item}
keyExtractor={(index, item) => item}
style={{ flexGrow: 0 }} // This was the solution to centering
/>
</ScrollView>
</View>
<View style={{ flex: 1 }}>
<Text>FOOTER</Text>
</View>
</View>
);
}
Here's the final Working Solution if you'd like to try it.
Update 1:
Managed to control ScrollView size with Flex normally (that is using integer flex values as intended in the first place) by wrapping ScrollView inside a View with flex: 1
.
The downside is that if I set the Scrollable section (content) to a flex value high enough so It's not scrollable anymore, content doesn't display centered. Not even if justifyContent: 'center'
is applied.
Here's UPDATE 1 example.