Реагировать на родную гибкую коробку, не используя все доступное пространство

У меня есть макет, который я хочу сделать в полноэкранном режиме. Вот как это выглядит прямо сейчас: введите описание изображения здесь

Я хочу, чтобы макет занимал все пространство на экране (поэтому кнопка отправки должна быть внизу вниз). Я пытаюсь использовать {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\ 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}). Любые предложения?

Ответ 1

То, что вы хотите, - это поддержка contentContainerStyle компонента ScrollView. Если вы замените:

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

с:

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

Это устранит вашу проблему.

Как указано в документе:

Эти стили будут применены к контейнеру содержимого прокрутки, который обертывает все дочерние представления.

Надеюсь, что это поможет!

Ответ 2

Если цвета являются точными на снимке экрана, ваш scrollview занимает все пространство по вертикали уже, но контейнер отсутствует (цвет фона контейнера белый). Это иллюстрирует работу scrollviews. Они действуют как контейнеры, где 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'
  }
})

Ответ 3

Вам нужно установить свойство flexDirection: 'row' для внешнего контейнера:

scroller: {
  flex:1,
  flexDirection: 'row'
}

Я установил базовую версию вашего приложения здесь. Остальная часть кода будет вставлена ​​ниже для полного рабочего примера:

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);