React Native:在 ScrollView contentContainerStyle 上设置 flex:1 会导致组件重叠
React Native: Setting flex:1 on a ScrollView contentContainerStyle causes overlapping of components
问题:
我有一个带有 2 个子视图的 ScrollView,我希望其中第一个(我们称之为 ViewA)具有 {flex: 1},这样另一个 (ViewB) 将固定在屏幕底部 - 但仅如果它们的总高度小于屏幕。当然,如果它们高于屏幕,我希望它像往常一样滚动。
案例 1(良好):带有长文本的 ViewA,ViewB 随之滚动。 https://rnplay.org/apps/slCivA
情况 2(不好):ViewA 带有短文本,ViewB 不粘在底部。 https://rnplay.org/apps/OmQakQ
尝试过的解决方案:
所以我将 ScrollView 的样式和 contentContainerStyle 设置为 flex: 1. 我
同时将 ViewA 的样式设置为 flex:1。但是当我这样做时,ScrollView 的 contentContainer 视图被固定到屏幕高度,因此无法在需要时滚动,甚至更糟 - ViewB 与 ViewA 重叠。
情况 3(错误):ViewB 粘在底部,但整个内容不滚动。 https://rnplay.org/apps/wZgtWA
如果它是一个错误 - 如何 fix/workaround 它?
如果这是预期的行为 - 我怎样才能实现我所描述的?
谢谢。
好的,我做了一个示例 here,我想我已经解决了问题。我做的主要事情是制作一个带有两个内部视图的主容器视图,然后将内部视图设置为 80% 和 20% 的弹性(您可以调整使其看起来像您想要的样子)。
好的,所以我无法通过单独的样式让它工作,但我是这样做的:
- 渲染后测量页脚的高度(使用
onLayout
和 measure
)
- 在
measure
回调中,我将高度(如果需要)添加到 ViewA 和 ViewB 之间的间隔视图,以便将 ViewB 放在底部。
- 为了避免向用户显示 'jumps',我隐藏(不透明)ViewB 直到它的位置固定。
我的 CJSX 代码(精简版):
Dimensions = require('Dimensions')
windowSize = Dimensions.get('window')
MyClass = React.createClass
mixins: [TimerMixin]
render: ->
<ScrollView style={styles.container} automaticallyAdjustContentInsets={false}>
<View style={styles.mainContainer}>
... THIS IS VIEW A ...
</View>
{
if !@state.footerWasFixed
<View>
<ActivityIndicatorIOS/>
</View>
}
<View style={[styles.spacer, {height: @state.spacerSize || 0}]}></View>
<View onLayout={@measureFooterPosition} style={[styles.extras, {opacity: if @state.footerWasFixed then 1 else 0 }]} ref='extras'>
... THIS IS VIEW B ...
</View>
</ScrollView>
measureFooterPosition: ->
@refs.extras.measure(@fixFooterPosition)
fixFooterPosition: (ox, oy, width, height) ->
footerPosition = Math.round(oy + height)
diff = windowSize.height - footerPosition
if diff > 0
@setState(spacerSize: diff)
if !@state.footerWasFixed
@setTimeout (=>
@setState(footerWasFixed: true)
), 30
styles = StyleSheet.create(
container:
backgroundColor: 'grey'
flex: 1
spacer:
backgroundColor: 'white'
mainContainer:
flex: 1
backgroundColor: 'white'
extras:
backgroundColor: 'white')
这是非常简化的代码,(我的观点要求比这个更具体..)但我希望它对任何人都有帮助。
尝试将 {flexGrow: 1}
喂给 contentContainerStyle 道具
问题:
我有一个带有 2 个子视图的 ScrollView,我希望其中第一个(我们称之为 ViewA)具有 {flex: 1},这样另一个 (ViewB) 将固定在屏幕底部 - 但仅如果它们的总高度小于屏幕。当然,如果它们高于屏幕,我希望它像往常一样滚动。
案例 1(良好):带有长文本的 ViewA,ViewB 随之滚动。 https://rnplay.org/apps/slCivA
情况 2(不好):ViewA 带有短文本,ViewB 不粘在底部。 https://rnplay.org/apps/OmQakQ
尝试过的解决方案:
所以我将 ScrollView 的样式和 contentContainerStyle 设置为 flex: 1. 我 同时将 ViewA 的样式设置为 flex:1。但是当我这样做时,ScrollView 的 contentContainer 视图被固定到屏幕高度,因此无法在需要时滚动,甚至更糟 - ViewB 与 ViewA 重叠。
情况 3(错误):ViewB 粘在底部,但整个内容不滚动。 https://rnplay.org/apps/wZgtWA
如果它是一个错误 - 如何 fix/workaround 它? 如果这是预期的行为 - 我怎样才能实现我所描述的?
谢谢。
好的,我做了一个示例 here,我想我已经解决了问题。我做的主要事情是制作一个带有两个内部视图的主容器视图,然后将内部视图设置为 80% 和 20% 的弹性(您可以调整使其看起来像您想要的样子)。
好的,所以我无法通过单独的样式让它工作,但我是这样做的:
- 渲染后测量页脚的高度(使用
onLayout
和measure
) - 在
measure
回调中,我将高度(如果需要)添加到 ViewA 和 ViewB 之间的间隔视图,以便将 ViewB 放在底部。 - 为了避免向用户显示 'jumps',我隐藏(不透明)ViewB 直到它的位置固定。
我的 CJSX 代码(精简版):
Dimensions = require('Dimensions')
windowSize = Dimensions.get('window')
MyClass = React.createClass
mixins: [TimerMixin]
render: ->
<ScrollView style={styles.container} automaticallyAdjustContentInsets={false}>
<View style={styles.mainContainer}>
... THIS IS VIEW A ...
</View>
{
if !@state.footerWasFixed
<View>
<ActivityIndicatorIOS/>
</View>
}
<View style={[styles.spacer, {height: @state.spacerSize || 0}]}></View>
<View onLayout={@measureFooterPosition} style={[styles.extras, {opacity: if @state.footerWasFixed then 1 else 0 }]} ref='extras'>
... THIS IS VIEW B ...
</View>
</ScrollView>
measureFooterPosition: ->
@refs.extras.measure(@fixFooterPosition)
fixFooterPosition: (ox, oy, width, height) ->
footerPosition = Math.round(oy + height)
diff = windowSize.height - footerPosition
if diff > 0
@setState(spacerSize: diff)
if !@state.footerWasFixed
@setTimeout (=>
@setState(footerWasFixed: true)
), 30
styles = StyleSheet.create(
container:
backgroundColor: 'grey'
flex: 1
spacer:
backgroundColor: 'white'
mainContainer:
flex: 1
backgroundColor: 'white'
extras:
backgroundColor: 'white')
这是非常简化的代码,(我的观点要求比这个更具体..)但我希望它对任何人都有帮助。
尝试将 {flexGrow: 1}
喂给 contentContainerStyle 道具