React原生弹性框不使用所有可用空间

时间:2015-12-13 16:29:51

标签: android ios reactjs flexbox react-native

我有一个我要全屏制作的布局。这就是它现在的样子:enter image description here

我想要的是布局占用屏幕上的所有空间(因此提交按钮应该在底部向下)。我试图使用{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}为好)。有什么建议吗?

3 个答案:

答案 0 :(得分:12)

您想要的是contentContainerStyle组件的ScrollView道具。如果你替换:

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

with:

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

这将解决您的问题。

如上所述in the doc

  

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

希望它有所帮助!

答案 1 :(得分:1)

如果屏幕截图中的颜色准确,则您的滚动视图已占用所有垂直空间但容器不占用(容器背景颜色为白色)。这说明了scrollviews的工作原理。它们充当容器,其中柔性可以真正使儿童生长以适应垂直空间,因为它可能是无限的。而是将孩子们渲染到自然高度。 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 :(得分:-1)

您需要为最外层容器设置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);