使用 ScrollView 的 Flex 布局
Flex layout with ScrollView
我使用 Flexbox 在 React Native 中制作屏幕布局已有一段时间了,直到今天我不得不制作这个非常简单的布局时才 运行 遇到任何麻烦:
- A header 部分(不是 NavBar)。
- content 部分 → 一个带有 FlatList 的 ScrollView。
- 一个页脚部分。
我希望内容部分比页眉和页脚大3倍,所以很自然地我将flex设置为1(页眉)、3(内容)、1(页脚)。
不管怎么说,内容还是有 flex: 1
.
我可以按照我想要的方式控制布局的唯一方法是保留内容的 flex: 1
并将页脚和页眉都设置为 flex: 0.33
.
我怀疑这可能与我设置为 flexGrow: 1, flexShrink: 1
.
的 ScrollView 的 contentContainerStyle 道具有关
这里有一个 minimal example 重现了这个。
经过最小的修改它对我有用,我使用了这种风格:
const styles = StyleSheet.create({
screen: {
backgroundColor: 'lightgray',
flex: 1,
},
header: {
flex: 0.33,
backgroundColor: 'lightblue',
justifyContent: 'center',
alignItems: 'center',
},
scrollView: {
flex: 1,
},
footer: {
backgroundColor: 'lightpink',
flex: 0.33,
alignItems: 'center',
justifyContent: 'center',
},
});
完整代码>>> https://snack.expo.io/Hk9tbHR4Q
这是结果:
更新二:
有人指出我不应该使用包裹在 ScrollView 中的 ListView,因为可能会发生以下情况:
这可能会导致一些奇怪的行为,例如 onEndReached
连续射击。
将 ListView 包裹在 ScrollView 中使父滚动操作支配子滚动操作,从而仅导致 ScrollView 滚动。
好的,我不确定为什么会这样,但经过数小时的尝试找到了解决方案:
在Update 1中提到的步骤之后,我在FlatList中添加了以下样式flexGrow: 0
ScrollView 并且内容居中并减小内容的大小直到它变成可滚动的效果也很好。
基本上这是生成的代码:
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>
);
}
这是最后的Working Solution,如果你想试试的话。
更新 1:
通过用 flex: 1
将 ScrollView 包装在 View 中,设法正常控制 Flex 的 ScrollView 大小(即首先使用整数 flex 值)。
不利之处在于,如果我将可滚动部分(内容)设置为足够高的弹性值以使其不再可滚动,则内容不会居中显示。即使应用 justifyContent: 'center'
也不行。
这里是UPDATE 1 example。
我使用 Flexbox 在 React Native 中制作屏幕布局已有一段时间了,直到今天我不得不制作这个非常简单的布局时才 运行 遇到任何麻烦:
- A header 部分(不是 NavBar)。
- content 部分 → 一个带有 FlatList 的 ScrollView。
- 一个页脚部分。
我希望内容部分比页眉和页脚大3倍,所以很自然地我将flex设置为1(页眉)、3(内容)、1(页脚)。
不管怎么说,内容还是有 flex: 1
.
我可以按照我想要的方式控制布局的唯一方法是保留内容的 flex: 1
并将页脚和页眉都设置为 flex: 0.33
.
我怀疑这可能与我设置为 flexGrow: 1, flexShrink: 1
.
这里有一个 minimal example 重现了这个。
经过最小的修改它对我有用,我使用了这种风格:
const styles = StyleSheet.create({
screen: {
backgroundColor: 'lightgray',
flex: 1,
},
header: {
flex: 0.33,
backgroundColor: 'lightblue',
justifyContent: 'center',
alignItems: 'center',
},
scrollView: {
flex: 1,
},
footer: {
backgroundColor: 'lightpink',
flex: 0.33,
alignItems: 'center',
justifyContent: 'center',
},
});
完整代码>>> https://snack.expo.io/Hk9tbHR4Q
这是结果:
更新二:
有人指出我不应该使用包裹在 ScrollView 中的 ListView,因为可能会发生以下情况:
这可能会导致一些奇怪的行为,例如
onEndReached
连续射击。将 ListView 包裹在 ScrollView 中使父滚动操作支配子滚动操作,从而仅导致 ScrollView 滚动。
好的,我不确定为什么会这样,但经过数小时的尝试找到了解决方案:
在Update 1中提到的步骤之后,我在FlatList中添加了以下样式flexGrow: 0
ScrollView 并且内容居中并减小内容的大小直到它变成可滚动的效果也很好。
基本上这是生成的代码:
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>
);
}
这是最后的Working Solution,如果你想试试的话。
更新 1:
通过用 flex: 1
将 ScrollView 包装在 View 中,设法正常控制 Flex 的 ScrollView 大小(即首先使用整数 flex 值)。
不利之处在于,如果我将可滚动部分(内容)设置为足够高的弹性值以使其不再可滚动,则内容不会居中显示。即使应用 justifyContent: 'center'
也不行。
这里是UPDATE 1 example。