106 votes

React Native FlatList avec colonnes, Dernière largeur d'élément

J'utilise une FlatList pour afficher une liste d'éléments sur deux colonnes.

<FlatList style={{margin:5}}
  data={this.state.items}
  numColumns={2}
  keyExtractor={(item, index) => item.id }
  renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>

Le composant carte est juste une vue avec quelques styles :

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130}} ></View>

Le système fonctionne bien, mais si le nombre d'éléments est impair, la dernière ligne ne contient qu'un seul élément et celui-ci s'étend sur toute la largeur de l'écran.

Comment puis-je régler l'élément à la même largeur que les autres ?

enter image description here

101voto

Emilius Mfuruki Points 151

Pour votre cas utiliser flex : 1/2

donc : Votre article aurait dû flex de 1/(nombre de colonnes) si vous avez 3 colonnes votre article devrait avoir flex:1/3

3 votes

Je ne sais pas pourquoi ce n'est pas marqué comme la réponse. C'est la solution la plus simple et la plus correcte !

15 votes

Lorsque je donne flex : 1/2, la largeur du dernier élément est plus grande que celle des éléments précédents. Comment pouvons-nous résoudre ce problème ?

0 votes

Geniussss ! !! ça a marché ! la meilleure solution de contournement jamais vue. Merci mec, tu mérites la bonne réponse

46voto

Ryan Turnbull Points 2057

Il y a plusieurs choses que vous pouvez essayer ici.

A) Définir une largeur prédéfinie pour la carte (peut-être égale à la hauteur que vous avez définie ?). Vous pouvez alors utiliser alignItems afin que la carte soit positionnée au milieu ou à gauche - Je ne suis pas sûr de savoir ce que vous vouliez ici.

B) S'il y a un nombre pair de cartes, vous pourriez ajouter une vue vide à la fin afin de remplir cet espace. Je trouve cette méthode plutôt maladroite mais utile lorsqu'on essaie de laisser de la place pour des éléments futurs.

C) Utilisez simplement alignItems: 'space-between J'aime l'utiliser pour centrer les éléments, mais vous devez définir la largeur, ou utiliser quelque chose comme flex:0.5

Je vous suggère de faire des recherches plus approfondies sur le système Flexbox pour vous aider dans ce domaine, car il est difficile de déterminer le contexte de cette situation. Je suppose que les méthodes ci-dessus vous aideront, mais si ce n'est pas le cas, voici quelques liens que vous pouvez consulter

Premier lien

Deuxième lien

Troisième lien <em>Lien brisé</em>

J'espère que cela vous aidera. Si vous avez besoin de plus d'informations, n'hésitez pas à nous contacter.

2 votes

B est un pirate raisonnable. L'option A est redondante, on peut simplement aligner ces éléments en ajoutant flexWrap. Quel est l'intérêt de numColumns dans ce cas ?

0 votes

J'étais réticent à l'idée d'opter pour B, mais je l'ai fait, et même si c'est un hack, cela fonctionne bien, et je n'ai pas besoin de spécifier la largeur des éléments (je veux qu'ils s'adaptent à la largeur disponible).

0 votes

@Ryan : Je veux que la première cellule soit entièrement étirée et avec 3 colonnes, que dois-je faire ?

20voto

skyplor Points 148

Vous pouvez essayer d'obtenir la largeur actuelle de l'appareil via Dimensions, faire des calculs basés sur le nombre de colonnes que vous souhaitez rendre, déduire les marges et définir ces valeurs comme largeur minimale et maximale.

Par exemple :

const {height, width} = Dimensions.get('window');
const itemWidth = (width - 15) / 2;

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', minWidth: {this.itemWidth}, maxWidth: {this.itemWidth}, height: 130}} ></View>

0 votes

Je me suis retrouvé dans la même situation et je préfère nettement cette solution. Non seulement elle est plus simple, mais elle est aussi plus logique puisque, en fin de compte, nous voulons limiter le nombre d'utilisateurs de l flex:1 dans le cas d'une colonne impaire

0 votes

Très bien. Merci !

0 votes

Obtention d'une erreur : Les types de la propriété 'style' sont incompatibles

10voto

Tùng Nguyễn Points 1

La raison en est que votre carte a du style flex: 1 Il va donc essayer d'étendre tout l'espace restant. Vous pouvez résoudre ce problème en ajoutant maxWidth: '50%' à votre style de carte

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>

0 votes

La solution la plus simple qui soit

-1voto

Supriya C S Points 77

Vérifier si le nombre d'éléments est impair, si le nombre est impair, donner un style spécial au dernier élément. eg)

 {this.props.count%2!= 0?
                <View style={this.props.entireList.indexOf(item) === this.props.entireList.length-1 ?stles.v1:styles.v2}></View>
 v1:{
 width:'48%'
}
v2:{
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X