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>
);
}
}
我的 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>
);
}
}