React Native:使用 ScrollView 时垂直居中
React Native: vertical centering when using ScrollView
我正在使用 React Native,但我在引入 ScrollView 后就无法保持元素的垂直居中。为了演示,我使用 React Native Playground 创建了 3 个应用程序。所有示例都有 2 页,可以通过点击蓝色按钮切换它们。
示例 1:
第一个示例显示的块在第 2 页上垂直居中。发生这种情况是因为容器应用了这些样式:
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
https://rnplay.org/apps/lb5wSQ
但是,一切换到第2页就出问题了,因为整个页面的内容放不下,所以我们需要一个ScrollView
。
示例 2
在此示例中,我将所有内容都包装在 ScrollView 中。这允许第 2 页滚动,但现在我失去了第 1 页的垂直居中。
https://rnplay.org/apps/DCgOgA
示例 3
为了尝试恢复第 1 页的垂直居中,我将 flex: 1
应用于 ScrollView 的 contentContainerStyle
。这修复了第 1 页的垂直居中问题,但我无法再一直向下滚动到第 2 页的底部。
https://rnplay.org/apps/LSgbog
我该如何解决这个问题,使第 1 页上的元素垂直居中,但仍然让 ScrollView 一直滚动到第 2 页的底部?
为什么不在 ScrollView 中只包裹第二页?
return (
<ScrollView >
<View style={styles.lipsum}>
{this.renderButton()}
<Text style={styles.lipsumText}>{lipsumText}</Text>
</View>
</ScrollView>
);
只要修改你的第一个例子,它就像一个魅力:)
编辑: 您现在可以使用 <ScrollView contentContainerStyle={{flexGrow: 1}}>
。
对于不支持 flexGrow
的旧版本 React Native,请使用以下解决方案。
我发现为 iOS 和 Android 可靠地执行此操作的唯一方法是将内部视图的 minHeight
设置为 ScrollView
的大小.例如:
<ScrollView
style={{flex: 1}}
contentContainerStyle={{minHeight: this.state.minHeight}}
onLayout={event => this.setState({minHeight: event.nativeEvent.layout.height})}
>
注意:为了简单起见,我已经内联了上面的样式和函数,但您可能希望对不变的值使用常量引用,并记住不断变化的样式以防止不必要的重新渲染。
const {minHeight} = this.state;
// Manually memorise changing style or use something like reselect...
if (this.lastMinHeight != minHeight) {
this.lastMinHeight = minHeight;
this.contentContainerStyle = {minHeight: minHeight}
}
<ScrollView
style={styles.scrollViewStyle}
contentContainerStyle={this.contentContainerStyle}
onLayout={this.onScrollViewLayout}
>
有一个新的解决方案(不幸的是 iOS 目前只有)- 我们可以在 Scrollview 上使用 centerContent
prop。
我用 flexGrow 而不是 flex 解决了这个问题
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
这使得内容容器伸展以填充 ScrollView 但不限制最大高度,因此当内容超出 ScrollView 的边界时您仍然可以正确滚动
这是我的方法:
使用带有 flex : 1
的外部容器,然后滚动视图需要 {flexGrow : 1, justifyContent : 'center'}
使用 contentContainerStyle
,而不是 style
。
<View style={styles.mainContainer}>
<ScrollView
contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}}>
<View style={styles.scrollViewContainer}>
//Put your stuff here, and it will be centered vertical
</View>
</ScrollView>
</View>
样式:
const styles = StyleSheet.create({scrollView : {
height : Dimensions.get('window').height, }, mainContainer : {
flex : 1 }, scrollViewContainer : { }, })
为了让 ScrollView 本身垂直居中,那么你需要有这样的结构:
<View style={{flex: 1}}>
<View>
<ScrollView .../>
</View>
</View>
否则,如果你想让 ScrollView 内容本身居中,那么你需要以下内容:
<ScrollView contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}} ...>
我正在使用 React Native,但我在引入 ScrollView 后就无法保持元素的垂直居中。为了演示,我使用 React Native Playground 创建了 3 个应用程序。所有示例都有 2 页,可以通过点击蓝色按钮切换它们。
示例 1:
第一个示例显示的块在第 2 页上垂直居中。发生这种情况是因为容器应用了这些样式:
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
https://rnplay.org/apps/lb5wSQ
但是,一切换到第2页就出问题了,因为整个页面的内容放不下,所以我们需要一个ScrollView
。
示例 2
在此示例中,我将所有内容都包装在 ScrollView 中。这允许第 2 页滚动,但现在我失去了第 1 页的垂直居中。
https://rnplay.org/apps/DCgOgA
示例 3
为了尝试恢复第 1 页的垂直居中,我将 flex: 1
应用于 ScrollView 的 contentContainerStyle
。这修复了第 1 页的垂直居中问题,但我无法再一直向下滚动到第 2 页的底部。
https://rnplay.org/apps/LSgbog
我该如何解决这个问题,使第 1 页上的元素垂直居中,但仍然让 ScrollView 一直滚动到第 2 页的底部?
为什么不在 ScrollView 中只包裹第二页?
return (
<ScrollView >
<View style={styles.lipsum}>
{this.renderButton()}
<Text style={styles.lipsumText}>{lipsumText}</Text>
</View>
</ScrollView>
);
只要修改你的第一个例子,它就像一个魅力:)
编辑: 您现在可以使用 <ScrollView contentContainerStyle={{flexGrow: 1}}>
。
对于不支持 flexGrow
的旧版本 React Native,请使用以下解决方案。
我发现为 iOS 和 Android 可靠地执行此操作的唯一方法是将内部视图的 minHeight
设置为 ScrollView
的大小.例如:
<ScrollView
style={{flex: 1}}
contentContainerStyle={{minHeight: this.state.minHeight}}
onLayout={event => this.setState({minHeight: event.nativeEvent.layout.height})}
>
注意:为了简单起见,我已经内联了上面的样式和函数,但您可能希望对不变的值使用常量引用,并记住不断变化的样式以防止不必要的重新渲染。
const {minHeight} = this.state;
// Manually memorise changing style or use something like reselect...
if (this.lastMinHeight != minHeight) {
this.lastMinHeight = minHeight;
this.contentContainerStyle = {minHeight: minHeight}
}
<ScrollView
style={styles.scrollViewStyle}
contentContainerStyle={this.contentContainerStyle}
onLayout={this.onScrollViewLayout}
>
有一个新的解决方案(不幸的是 iOS 目前只有)- 我们可以在 Scrollview 上使用 centerContent
prop。
我用 flexGrow 而不是 flex 解决了这个问题
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
这使得内容容器伸展以填充 ScrollView 但不限制最大高度,因此当内容超出 ScrollView 的边界时您仍然可以正确滚动
这是我的方法:
使用带有 flex : 1
的外部容器,然后滚动视图需要 {flexGrow : 1, justifyContent : 'center'}
使用 contentContainerStyle
,而不是 style
。
<View style={styles.mainContainer}>
<ScrollView
contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}}>
<View style={styles.scrollViewContainer}>
//Put your stuff here, and it will be centered vertical
</View>
</ScrollView>
</View>
样式:
const styles = StyleSheet.create({scrollView : {
height : Dimensions.get('window').height, }, mainContainer : {
flex : 1 }, scrollViewContainer : { }, })
为了让 ScrollView 本身垂直居中,那么你需要有这样的结构:
<View style={{flex: 1}}>
<View>
<ScrollView .../>
</View>
</View>
否则,如果你想让 ScrollView 内容本身居中,那么你需要以下内容:
<ScrollView contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}} ...>