React Native: centrage vertical lors de L'utilisation de ScrollView
J'utilise React Native et j'ai du mal à conserver le centrage vertical des éléments dès que j'introduis un ScrollView. Pour démontrer, j'ai créé 3 applications avec React Native Playground. Tous les exemples ont 2 pages, et ils peuvent être basculés en appuyant sur le bouton bleu.
Exemple 1:
Ce premier exemple montre les blocs centrés verticalement à la page 2. Cela se produit parce que ces styles sont appliqués au conteneur il:
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
Https://rnplay.org/apps/lb5wSQ
Cependant, il y a un problème dès que vous passez à la page 2, car tout le contenu de la page ne correspond pas, nous avons donc besoin d'un ScrollView
.
Exemple 2
Dans cet exemple, j'enroule tout à l'intérieur D'un ScrollView. Cela permet à la page 2 de faire défiler, mais maintenant j'ai perdu le centrage vertical de la Page 1.
Https://rnplay.org/apps/DCgOgA
Exemple 3
Afin de essayez de récupérer le centrage vertical de la Page 1, j'applique flex: 1
au contentContainerStyle
de ScrollView. Cela corrige le centrage vertical sur la page 1, mais je ne suis plus en mesure de faire défiler tout le chemin vers le bas sur la page 2.
Https://rnplay.org/apps/LSgbog
Comment puis-je résoudre ce problème pour obtenir le centrage vertical des éléments sur la page 1 tout en obtenant ScrollView pour faire défiler tout le chemin vers le bas sur la page 2?
5 réponses
J'ai résolu ce problème avec flexGrow au lieu de flex
<ScrollView contentContainerStyle={{flexGrow: 1}}>
Cela permet au conteneur de contenu de s'étirer pour remplir le ScrollView mais ne limite pas la hauteur maximale, de sorte que vous pouvez toujours faire défiler correctement lorsque le contenu étend les limites du ScrollView
Voici mon approche:
Utilisez un conteneur externe avec flex : 1
, alors la vue de défilement doit avoir {flexGrow : 1, justifyContent : 'center'}
en utilisant contentContainerStyle
, Pas style
.
<View style={styles.mainContainer}>
<ScrollView
contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}}>
<View style={styles.scrollViewContainer}>
//Put your stuff here, and it will be centered vertical
</View>
</ScrollView>
</View>
Styles:
const styles = StyleSheet.create({scrollView : {
height : Dimensions.get('window').height, }, mainContainer : {
flex : 1 }, scrollViewContainer : { }, })
Il y a une nouvelle solution (malheureusement iOS seulement pour le moment) - nous pouvons utiliser centerContent
prop sur Scrollview.
EDIT: Vous pouvez maintenant utiliser <ScrollView contentContainerStyle={{flexGrow: 1}}>
.
Pour les anciennes versions de React Native qui ne prennent pas en charge flexGrow
, Utilisez la solution ci-dessous.
La seule façon que j'ai trouvée pour le faire de manière fiable pour iOS et Android est de définir minHeight
de la vue interne à la taille du ScrollView
. Par exemple:
<ScrollView
style={{flex: 1}}
contentContainerStyle={{minHeight: this.state.minHeight}}
onLayout={event => this.setState({minHeight: event.nativeEvent.layout.height})}
>
Note: j'ai intégré les styles et les fonctions ci-dessus pour plus de simplicité, mais vous voudrez probablement utiliser des références constantes pour les valeurs immuables et mémoriser le style changeant pour éviter les redirections inutiles.
const {minHeight} = this.state;
// Manually memorise changing style or use something like reselect...
if (this.lastMinHeight != minHeight) {
this.lastMinHeight = minHeight;
this.contentContainerStyle = {minHeight: minHeight}
}
<ScrollView
style={styles.scrollViewStyle}
contentContainerStyle={this.contentContainerStyle}
onLayout={this.onScrollViewLayout}
>
Pourquoi ne pas envelopper seulement la deuxième page dans un ScrollView?
return (
<ScrollView >
<View style={styles.lipsum}>
{this.renderButton()}
<Text style={styles.lipsumText}>{lipsumText}</Text>
</View>
</ScrollView>
);
Modifiez simplement votre premier exemple, cela fonctionne comme un charme:)