ScrollView 中的 React Native v0.42 flexbox 错误

React Native v0.42 flexbox error in ScrollView

我的 React Native 渲染代码是:

<ScrollView
  contentContainerStyle={{
    minHeight: 100,
    flexDirection: "column",
    alignItems: "stretch",
    marginTop: 16,
  }}
  alwaysBounceVertical={false}
  showsVerticalScrollIndicator={false}
>
    <View style={{flex: 0.5, backgroundColor: "green"}}>
        <View style={{height: 10, backgroundColor: "yellow"}}/>
    </View>
    <View style={{flex: 0.5, backgroundColor: "blue"}}/>
</ScrollView>

上面的代码应该呈现 2 个视图,每个高度 50,顶部一个绿色,底部一个黄色。在顶视图里面,应该有一个高度为10的黄色视图。

相反,它渲染了高度为 60 的顶部视图和高度为 50 的底部框。顶部框内部有一个高度为 10 的框。颜色都是正确的。

但是,如果我将 height:10 部分更改为 height:"20%",则一切正常。

我该如何解决这个问题?

谢谢。

您可以绝对定位黄色视图:

<ScrollView
  contentContainerStyle={{
    minHeight: 100,
    flexDirection: "column",
    alignItems: "stretch",
    marginTop: 16,
  }}
  alwaysBounceVertical={false}
  showsVerticalScrollIndicator={false}
>
  <View style={{flex: 0.5, backgroundColor: "green"}}>
    <View style={{
      height: 10, 
      backgroundColor: "yellow", 
      position: 'absolute',
      top: 0, left: 0, right: 0 
    }}/>
  </View>
  <View style={{flex: 0.5, backgroundColor: "blue"}}/>
</ScrollView>

或者在 ScrollView 上使用固定高度:

<ScrollView
  contentContainerStyle={{
    height: 100,
    flexDirection: "column",
    alignItems: "stretch",
    marginTop: 16,
  }}
  alwaysBounceVertical={false}
  showsVerticalScrollIndicator={false}
>

这个问题的解决方案是将 "green" 视图包装在一个组件中,例如(我正在使用打字稿):

class VerticalScrollingContentContainer extends
    React.PureComponent<{style?: Styles},
    {mainViewHeight: number, isMeasured: boolean}> {

constructor(props: any) {
    super(props);
    this.state = {
        mainViewHeight: 0,
        isMeasured: false,
    };
}

layoutReceived = (width: number, height: number) => {
    let newHeight = height > width ? height : width;
    this.setState(
        oldState => ({mainViewHeight: newHeight, isMeasured: true})
    );
}

render() {
    let isMeasured = this.state.isMeasured;
    let mainViewHeight = this.state.mainViewHeight;
    let innerContainerLayout = {
        flexDirection: "column",
    };
    if (!isMeasured) {
        innerContainerLayout = {
            ...innerContainerLayout,
            flex: 1
        };
    } else {
        innerContainerLayout = {
            ...innerContainerLayout,
            minHeight: mainViewHeight
        };
    }
    return (
        <ScrollView
            style={{flex: 1}}
            contentContainerStyle={innerContainerLayout as any}
            alwaysBounceVertical={false}
            showsVerticalScrollIndicator={false}>
            <View
                style={[
                    {
                        flexGrow: 1,
                        alignItems: "flex-start",
                        flexDirection: "column",
                    },
                    this.props.style
                ]}
                onLayout={(e) => {
                    this.layoutReceived(e.nativeEvent.layout.width, e.nativeEvent.layout.height); }}>
                {this.props.children}
            </View>
        </ScrollView>
    );
}

}