反应原生弹性盒不使用所有可用空间

Posted

技术标签:

【中文标题】反应原生弹性盒不使用所有可用空间【英文标题】:React native flex box not using all available space 【发布时间】:2016-03-19 03:05:43 【问题描述】:

我有一个想要全屏显示的布局。这就是它现在的样子:

我想要的是布局占据屏幕上的所有空间(因此提交按钮应该在底部向下)。我正在尝试使用flex: 1,但它不起作用。代码如下:

'use strict';

const React = require('react-native');
const 
  StyleSheet,
  Text,
  View,
  Backandroid,
  TextInput,
  TouchableNativeFeedback,
  ScrollView
 = React;

const ActionButton = require('./action-button');

module.exports = React.createClass(
  handleBackButtonPress () 
    if (this.props.navigator) 
      this.props.navigator.pop();
      return true;
    

    return false;
  ,

  componentWillMount () 
    BackAndroid.addEventListener('hardwareBackPress', this.handleBackButtonPress);
  ,

  componentWillUnmount () 
    BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButtonPress);
  ,

  onInputFocus (refName) 
    setTimeout(() => 
      let scrollResponder = this.refs.scrollView.getScrollResponder();
      scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
        React.findNodeHandle(this.refs[refName]),
        0,
        true
      );
    , 50);
  ,

  render: function() 
    return (
      <ScrollView ref='scrollView' style=styles.scroller>
        <View style=styles.container>
          <View style=styles.header>
            <Text>New Post</Text>

              <View style=styles.actions>
                <ActionButton handler=this.handleBackButtonPress icon='fontawesome|close'
                  size=15 width=15 height=15 />
              </View>
          </View>
          <View style=styles.content>
            <TextInput underlineColorAndroid='white'
              placeholder='Who\'s your professor?'
              ref='professor'
              onFocus=this.onInputFocus.bind(this, 'professor')
              style=styles.professor
              />

            <TextInput multiline=true
              underlineColorAndroid='white'
              placeholder='What do you think?'
              ref='post'
              onFocus=this.onInputFocus.bind(this, 'post')
              style=styles.post
              />
          </View>
          <View style=styles.footer>
            <TouchableNativeFeedback
              background=TouchableNativeFeedback.SelectableBackground()>

              <View style=width: 50, height: 25, backgroundColor: 'green'>
                <Text>Submit</Text>
              </View>
            </TouchableNativeFeedback>
          </View>
        </View>
      </ScrollView>
    );
  
);

const styles = StyleSheet.create(
  scroller: 
    flex: 1,
    flexDirection: 'column'
  ,
  container: 
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'flex-start',
    backgroundColor: 'white',
    padding: 5,
  ,
  post: 
    flex: 3
  ,
  professor: 
    flex: 1
  ,
  actions: 
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'flex-end',
    alignSelf: 'center'
  ,
  header: 
    flex: 1,
    padding: 5,
    flexDirection: 'row'
  ,
  content: 
    flex: 4
  ,
  footer: 
    flex: 1
  
);

据我所见,我一直在视图层次结构中设置 flex 属性,但这仍然没有做任何事情(在顶层也是一个带有 flex: 1 的 Navigator)。有什么建议吗?

【问题讨论】:

您是否将此视图包含在另一个容器中? 【参考方案1】:

如果屏幕截图中的颜色准确,则您的滚动视图已经占用了所有垂直空间,但容器不是(容器背景颜色为白色)。这说明了滚动视图是如何工作的。它们充当容器,其中 flex 不能真正让孩子成长以适应垂直空间,因为它可能是无限的。相反,孩子们被渲染在他们的自然高度。 http://devdocs.io/react_native/scrollview

尝试使用占据整个屏幕高度的视图。

<View style=styles.container>
  ... components here ...
</View>
const styles = StyleSheet.create(
  container: 
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between'
  
)

【讨论】:

【参考方案2】:

你想要的是ScrollView 组件的contentContainerStyle 属性。如果你更换:

<ScrollView ref='scrollView' style=styles.scroller>

与:

<ScrollView ref='scrollView' contentContainerStyle=styles.scroller>

这会解决你的问题。

如in the doc 所述:

这些样式将应用于包含所有子视图的滚动视图内容容器。

希望对你有帮助!

【讨论】:

这立即解决了我的问题。但是,当内容超过视图底部时,它使 ScrollView 停止滚动,因此它基本上通过将 style 更改为 contentContainerStyle 将其变成了 。我同时尝试了两者,但也没有按预期工作。 相同。这不适用于 RN 0.48/Expo 21.0。编辑,这似乎有效:contentContainerStyle= flexGrow: 1 . 使用contentContainerStyle=flexGrow:1 对我也有用。谢谢!【参考方案3】:

你需要为最外层的容器设置一个 flexDirection: 'row' 属性:

scroller: 
  flex:1,
  flexDirection: 'row'

我已经为您的应用设置了基本版本here。其余代码粘贴在下面以获取完整的工作示例:

https://rnplay.org/apps/gjBqgw

'use strict';

var React = require('react-native');
var 
  StyleSheet,
  Text,
  View,
  BackAndroid,
  TextInput,
  TouchableNativeFeedback,
  ScrollView,
  AppRegistry,
  TouchableHighlight
 = React;

var SampleApp = React.createClass(
   render: function() 
    return (
      <ScrollView ref='scrollView' style=styles.scroller>
        <View style=styles.container>
          <View style=styles.header>
            <Text>New Post</Text>

              <View style=styles.actions>
                <TouchableHighlight handler=this.handleBackButtonPress icon='fontawesome|close'
                  size=15 width=15 height=15>
                            <Text>Button Text</Text>
                        </TouchableHighlight>
              </View>
          </View>
          <View style=styles.content>
           <Text>Hello from content</Text>
          </View>
          <View style=styles.footer>
            <TouchableHighlight>

              <View style=width: 50, height: 25, backgroundColor: 'green'>
                <Text>Submit</Text>
              </View>
            </TouchableHighlight>
          </View>
        </View>
      </ScrollView>
    );

  
);

const styles = StyleSheet.create(
  scroller: 
    flex:1,
    flexDirection: 'row'
  ,
  container: 
    flex: 1,
    backgroundColor: 'white',
    padding: 5,
  ,
  post: 
    flex: 3
  ,
  professor: 
    flex: 1
  ,
  actions: 
    flex: 1,
    flexDirection: 'row',
    alignSelf: 'center'
  ,
  header: 
    flex: 1,
    padding: 5,
    flexDirection: 'row'
  ,
  content: 
    flex: 4
  ,
  footer: 
    flex: 1,
  
);

AppRegistry.registerComponent('SampleApp', () => SampleApp);

【讨论】:

为什么将 flex-direction 作为行来解决问题?它不是使主轴左右吗?并做 flex: 1 在水平方向占用整个可用空间? @nader-dabit 我尝试了你的建议,但它只是让内容消失了。

以上是关于反应原生弹性盒不使用所有可用空间的主要内容,如果未能解决你的问题,请参考以下文章

css 这定义了沿主轴的对齐。它可以帮助分配线上所有弹性项目时留下的额外可用空间

反应原生布局固定宽度并拉伸剩余空间

C3弹性盒子及弹性布局

是否可以隐藏弹性图表的轴并且不占用任何空间?

弹性盒模型

css3弹性盒模型(Flexbox)