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'}} ...>