web-dev-qa-db-fra.com

Réagir à la flex box native en n'utilisant pas tout l'espace disponible

J'ai une mise en page que je veux faire en plein écran. Voici à quoi cela ressemble maintenant:  enter image description here

Ce que je veux, c'est que la mise en page occupe toute la place à l'écran (le bouton d'envoi doit donc être placé tout en bas). J'essaie d'utiliser {flex: 1} mais cela ne fonctionne pas. Voici le code:

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

D'après ce que je peux voir, je règle la propriété flex tout au long de la hiérarchie des vues, mais cela ne fait toujours rien (au niveau supérieur, un navigateur avec {flex: 1} également). Aucune suggestion?

12
Hugo

Ce que vous voulez, c'est le prop contentContainerStyle du composant ScrollView. Si vous remplacez:

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

avec :

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

Cela résoudra votre problème.

Comme indiqué dans la doc :

Ces styles seront appliqués au conteneur de contenu de vue de défilement qui englobe toutes les vues enfants.

J'espère que ça aide!

12
VonD

Si les couleurs sont précises dans la capture d'écran, votre vue de défilement occupe déjà tout l'espace vertical, mais pas le conteneur (la couleur d'arrière-plan du conteneur est blanche). Ceci illustre le fonctionnement des vues de défilement. Ils agissent comme des conteneurs où le flex ne permet pas vraiment aux enfants de s’adapter à l’espace vertical qui est potentiellement infini. Au lieu de cela, les enfants sont rendus à leur hauteur naturelle. http://devdocs.io/react_native/scrollview

essayez plutôt d'utiliser une vue qui occupe toute la hauteur de l'écran.

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

Vous devez définir une propriété flexDirection: 'row' pour le conteneur le plus externe:

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

J'ai mis en place une version de base de votre application ici . Le reste du code est collé ci-dessous pour un exemple complet:

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);
0
Nader Dabit