web-dev-qa-db-fra.com

Comment positionner une vue en bas d'un ScrollView?

Je voudrais créer un écran avec un ScrollView avec quelques champs de saisie, et un bouton (en fait 2 boutons dans une vue normale) en bas de l'écran. Cela devrait être assez facile, MAIS, Je veux positionner mon bouton tout en bas de l'écran même si il n'y a pas assez d'élément dans ScrollView pour remplir tout l'écran. Je pourrais utiliser un positionnement absolu, MAIS mon ScrollView peut être plus grand (plus haut) que mon écran, et dans ce cas, le bouton devrait être à la fin du ScrollView. (Il serait donc hors de l'écran, ce qui signifie que l'utilisateur devrait faire défiler vers le bas pour voir le bouton).

J'ai essayé beaucoup de choses, mais le Button vient toujours juste après les autres éléments à l'intérieur de ScollView.

Dans l'image, la vue de défilement a une bordure bleue et la vue normale qui contient les boutons a une bordure noire.

Toute suggestion est appréciée.

enter image description here

8
Márk Farkas

J'ai trouvé la meilleure solution.

La clé est la propriété contentContainerStyle (doc: https://facebook.github.io/react-native/docs/scrollview#contentcontainerstyle ). "Ces styles seront appliqués au conteneur de contenu de vue de défilement qui encapsule toutes les vues enfant."

Après avoir défini flexGrow: 1, justificationContenu: 'espace entre', flexDirection: 'colonne' dans contentContainerStyle, on peut définir justificationContent: 'flex-start' pour la vue du conteneur supérieur avec le texte, et justificationContenu: 'flex-end' pour la vue du conteneur inférieur avec les boutons.

<ScrollView
  contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between', flexDirection: 'column' }}
  style={{ backgroundColor: 'white', paddingBottom: 20 }}
>
  <View style={{ flex: 1, justifyContent: 'flex-start' }}>
    <Text>Some text with different length in different cases, or some input fileds.</Text>
  </View>
  <View style={{ flex: 1, justifyContent: 'flex-end' }}>
    <View>
      <TouchableOpacity style={[commonStyles.greenButton, styles.buttonPadding]}>
        <Text style={commonStyles.greenButtonTitle}>Next</Text>
      </TouchableOpacity>
    </View>
    <View>
      <TouchableOpacity style={styles.cancelButtonContainer}>
        <Text style={styles.cancelButton}>Cancel</Text>
      </TouchableOpacity>
    </View>
  </View>
</ScrollView>;
21
Márk Farkas

J'ai trouvé une solution pour cela.

L'idée principale est de définir la hauteur de la vue avec les textes et les champs de saisie pour correspondre exactement à la hauteur de l'écran moins la vue qui contient les boutons .

Le défi est de calculer cette hauteur. La réponse d'Abhishek Kumar m'a aidé ( https://stackoverflow.com/a/41398953/4109477 ) Voir mon code ci-dessous:

         import { View, ScrollView, Text, TouchableOpacity, Dimensions } from 'react-native';

         const screenHeight = Dimensions.get('window').height;

          class MyClass extends React.Component {

          constructor(props) {
            super(props);
            this.state = {buttonViewHeight: 0};
          }

          find_dimesions(layout){
            this.setState({buttonViewHeight: layout.height});
          }
          render() {
            return (
              <View style={{minHeight: screenHeight, flex: 1, alignItems: 'center'}}>
                <ScrollView style={{minHeight: screenHeight}}>
                 <View style={{minHeight: screenHeight}}>
                    <View style={{minHeight: screenHeight - this.state.buttonViewHeight, borderWidth: 2, borderColor: 'red', alignItems: 'center', flex: 1}]}>
                      <Text>Some text with different length in different cases, or some input fileds.</Text>
                    </View>
                    <View onLayout={(event) => { this.find_dimesions(event.nativeEvent.layout) }} style={{paddingBottom: 50, flex: 1, borderWidth: 2, borderColor: 'green'}}>
                      <TouchableOpacity
                        style={[commonStyles.greenButton, styles.buttonPadding]} >
                        <Text style={commonStyles.greenButtonTitle}>Next</Text>
                      </TouchableOpacity>
                      <TouchableOpacity
                        style={styles.cancelButtonContainer} >
                        <Text style={styles.cancelButton}>Cancel</Text>
                      </TouchableOpacity>
                    </View>
                  </View>
                </ScrollView>
              </View>
          }
   }

Sur l'image ci-dessous, vous pouvez voir le résultat

This is how it looks now

Cette solution provoquera un effet similaire à une animation lorsque la vue sera rendue plusieurs fois, en raison du changement de la hauteur de la vue. La vue du bouton "fondu" lorsque vous ouvrez l'écran.

Si vous trouvez une meilleure solution, faites-le moi savoir!

0
Márk Farkas