sectionlist react flatlist example listview react-native

flatlist - Cuadrícula ListView en React Native



scrollview react native (8)

Estoy creando una aplicación simple en React Native que obtiene listados de una fuente JSON remota y los muestra en la pantalla.

Hasta ahora, usando el excelente example aquí, he logrado que los resultados se muestren usando los componentes ListView en filas (es decir, 1 resultado por fila, ver captura de pantalla). Necesito que los resultados se muestren en una cuadrícula, es decir, de 3 a 6 elementos por fila, según el tamaño y la orientación de la pantalla.

¿Cuál es la mejor manera de obtener estos resultados en una cuadrícula? ¿Puedo usar ListView para esto, o es solo para resultados de uno por fila? He intentado jugar con estilos de flexbox pero, dado que React no parece aceptar los valores de% y ListView no acepta estilos, todavía no he tenido éxito.


Consulte el siguiente ejemplo utilizando el componente FlatList de React Native para admitir el desplazamiento infinito con un rendimiento excelente:

//Resize the grid onLayout = (event) => { const {width} = event.nativeEvent.layout; const itemWidth = 150 const numColumns = Math.floor(width/itemWidth) this.setState({ numColumns: numColumns }) } render() { return ( <Content contentContainerStyle={{flex:1, alignItems: ''center''}} onLayout={this.onLayout}> <FlatList data={this.state.products} keyExtractor={(item, index) => index} key={this.state.numColumns} numColumns={this.state.numColumns} renderItem={({item}) => <ListThumb //Custom component, it''s only an example. navigation={navigation} brand={item.brand} price={item.price} imageSource={item.image_link}/> } /> </Content> ) }

El ejemplo se ve así

Saludos cordiales, Nicholls


Estoy agregando esto como respuesta porque los comentarios de desbordamiento están ocultos bajo la respuesta de Colin Ramsay: a partir de React Native 0.28, también necesita alignItems: ''flex-start'', en el estilo de vista de lista o el flexWrap no funcionará. Gracias a Kerumen en codedump.io por esto. Entonces,

var styles = StyleSheet.create({ list: { flexDirection: ''row'', flexWrap: ''wrap'', alignItems: ''flex-start'', },

... con el resto como en la respuesta de Colin.


ListView ahora está en deprecated y debería usar FlatList en FlatList lugar. FlatList tiene un accesorio llamado numColumns que es exactamente lo que queremos para crear una cuadrícula desplazable.

Por ejemplo:

const data = [ {id: ''a'', value: ''A''}, {id: ''b'', value: ''B''}, {id: ''c'', value: ''C''}, {id: ''d'', value: ''D''}, {id: ''e'', value: ''E''}, {id: ''f'', value: ''F''}, ]; const numColumns = 3; const size = Dimensions.get(''window'').width/numColumns; const styles = StyleSheet.create({ itemContainer: { width: size, height: size, }, item: { flex: 1, margin: 3, backgroundColor: ''lightblue'', } }); function Grid(props) { return ( <FlatList data={data} renderItem={({item}) => ( <View style={styles.itemContainer}> <Text style={styles.item}>{item.value}</Text> </View> )} keyExtractor={item => item.id} numColumns={numColumns} /> ); }

Esta publicación de blog hace un buen trabajo explicando las nuevas características de FlatList.

Nota: Por alguna razón, debe usar keyExtractor en la FlatList en lugar del típico accesorio de key en cada elemento. De lo contrario, recibirá una advertencia. Código básico FlatList arroja Advertencia - React Native


Puede usar FlatList y establecer numColumns para obtener el resultado que es el mismo con la cuadrícula


Sigue la respuesta de Colin Ramsay. Y si desea la mitad del ancho de cada elemento, intente de esta manera.

... import { Dimensions } from ''react-native''; const { width, height } = Dimensions.get(''window''); const gutter = 0; // You can add gutter if you want ... const styles = StyleSheet.create({ item: { width: (width - gutter * 3)/2, marginBottom: gutter, flexDirection: ''column'', alignSelf: ''flex-start'', backgroundColor: ''#ff0000'', }, list: { flexDirection: ''row'', justifyContent: ''space-between'', flexWrap: ''wrap'', paddingHorizontal: gutter, }, });


Tuve el mismo problema y escribí un componente que resuelve ese problema, puede encontrarlo aquí: https://github.com/pavlelekic/react-native-gridview

Además, otra cosa que hace este componente es asegurarse de que el ancho de los elementos sea un número entero, de modo que los bordes de los elementos no tengan suavizado, sean claros y nítidos.


use FlatList en lugar de Listview en react-native. Tiene más características de valor agregado y mejor rendimiento. FlatList


flexbox utilizar una combinación de flexbox y saber que ListView envuelve ScrollView y, por lo tanto, adquiere sus propiedades. Con eso en mente, puede usar el contenido contentContainerStyle de ScrollView para contentContainerStyle los elementos.

var TestCmp = React.createClass({ getInitialState: function() { var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); var data = Array.apply(null, {length: 20}).map(Number.call, Number); return { dataSource: ds.cloneWithRows(data), }; }, render: function() { return ( <ListView contentContainerStyle={styles.list} dataSource={this.state.dataSource} renderRow={(rowData) => <Text style={styles.item}>{rowData}</Text>} /> ); } });

Solo un ListView con algunos datos ficticios. Tenga en cuenta el uso de contentContainerStyle . Aquí está el objeto de estilo:

var styles = StyleSheet.create({ list: { flexDirection: ''row'', flexWrap: ''wrap'' }, item: { backgroundColor: ''red'', margin: 3, width: 100 } });

Le decimos al contenedor que queremos elementos en una fila de ajuste y establecemos el ancho de cada objeto secundario.