React Native:在ScrollView上设置flex:1 contentContainerStyle会导致组件重叠

时间:2015-11-12 15:14:54

标签: ios flexbox react-native

问题:

我有一个带有2个子视图的ScrollView,我希望第一个(让我们称之为ViewA)拥有{flex:1}所以另一个(ViewB)将坚持到屏幕的底部 - 但只有当他们的总高度小于屏幕。当然,如果它们高于屏幕,我希望它像往常一样滚动。

案例1(GOOD):带有长文本的ViewA,ViewB随之滚动。 https://rnplay.org/apps/slCivA

案例2(BAD):ViewA带有短文本,ViewB不会粘在底部。 https://rnplay.org/apps/OmQakQ

尝试过的解决方案:

所以我将ScrollView的样式和contentContainerStyle设置为flex:1。我 同时将ViewA的样式设置为flex:1。但是当我这样做时,ScrollView的contentContainer视图固定在屏幕高度上,因此如果需要则无法滚动,甚至更糟糕 - ViewB与ViewA重叠。

案例3(BAD):ViewB坚持到底部,但整个事情并没有滚动。 https://rnplay.org/apps/wZgtWA

如果它是一个错误 - 如何修复/解决它? 如果它是预期的行为 - 我怎样才能达到我所描述的目标?

感谢。

3 个答案:

答案 0 :(得分:37)

尝试将{flexGrow: 1}提供给contentContainerStyle道具

答案 1 :(得分:5)

好的,所以我单靠样式就无法让它发挥作用,但这就是我的表现:

  1. 在呈现后调整页脚的高度(使用onLayoutmeasure
  2. measure回调中,我将高度(如果需要)添加到ViewA和ViewB之间的间隔视图,以便将ViewB放在底部。
  3. 为了避免向用户显示“跳跃”,我隐藏(使用不透明度)ViewB,直到其位置固定为止。
  4. 我的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')
    

    这是非常简化的代码,(我的观点要求比这更具体......)但我希望它可以帮助任何人。

答案 2 :(得分:0)

好的,我已经制作了样本here,我想我已经解决了这个问题。我做的主要是制作一个带有两个内部视图的主容器视图,然后将内部视图设置为80%和20%的flex(您可以调整以使其看起来像您想要的那样)。

https://rnplay.org/apps/O4UxFA