Сетка ListView в React Native
Я создаю простое приложение в React Native, которое извлекает списки из удаленного источника JSON и отображает их на экране.
до сих пор, используя прекрасные пример здесь мне удалось получить результаты для отображения с помощью компонентов ListView в строках (т. е. 1 результат на строку, см. скриншот). Мне нужно, чтобы результаты отображались в сетке, т. е. от 3 до 6 элементов в строке, в зависимости от размера экрана и ориентации.
Что является лучшим способом, чтобы получить эти результаты в сетку? Могу ли я использовать ListView для этого, или это только для результатов по одной строке? Я пробовал играть со стилями flexbox, но, поскольку React, похоже, не принимает значения%, а ListView не принимает стили, у меня еще не было успеха.
8 ответов:
вы должны использовать комбинацию flexbox, и знание, что ListView обертывает ScrollView и поэтому принимает его свойства. Имея это в виду, вы можете использовать ScrollView
contentContainerStyle
опора для стиля элементы.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>} /> ); } });
просто ListView с некоторыми фиктивными данными. Обратите внимание на использование
contentContainerStyle
. Вот объект стиля:var styles = StyleSheet.create({ list: { flexDirection: 'row', flexWrap: 'wrap' }, item: { backgroundColor: 'red', margin: 3, width: 100 } });
мы говорим контейнеру, что хотим элементы в строке упаковки, и мы устанавливаем ширину каждого ребенка объект.
Я добавляю это в качестве ответа, потому что комментарии переполнения скрыты под ответом Колина Рамсея: начиная с React Native 0.28, вам также нужно
alignItems: 'flex-start',
в стиле listview или flexWrap не будет работать. Благодаря Kerumen on codedump.io за это. Итак,var styles = StyleSheet.create({ list: { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'flex-start', },
...с остальными, как в ответе Колина.
ListView теперь устаревший и вы должны использовать FlatList. FlatList имеет опору под названием
numColumns
это именно то, что мы хотим создать сетку.например:
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} /> ); }
этой блоге делает хорошую работу, объясняя новые возможности FlatList.
примечание: по какой-то причине вы должны использовать
keyExtractor
на FlatList вместо типичногоkey
опора на каждом элементе. В противном случае вы получите предупреждение. основной FlatList код выдает предупреждение-React Native
У меня была та же проблема, и я написал компонент, который решает эту проблему, вы можете найти его здесь:https://github.com/pavlelekic/react-native-gridview
кроме того, еще одна вещь, которую делает этот компонент, - это то, что ширина элементов является целым числом, так что границы элементов не имеют сглаживания, они четкие и четкие.
следуйте ответу Колина Рамзи. И если вы хотите половину ширины для каждого элемента, попробуйте этот способ.
... 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, }, });
используйте FlatList вместо Listview в react-native. он имеет более высокую добавленную стоимость и лучшую производительность. оформить заказ
вы можете использовать FlatList и установить numColumns для получения результата, который совпадает с grid
Проверьте следующий пример с помощью FlatList компонент Реагировать Уроженца для поддержки бесконечной прокрутки с отличной производительностью:
//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> ) }
пример выглядит так:
С наилучшими пожеланиями, Николс