Как я могу перечислить 2 столбца в React Native Flatlist, например:
Два столбца в RN FlatList
Ответы (6)
Просто передайте свойство numColumns вашему компоненту FlatList.
flex:1
заполнит ширину
- person MonoThreaded; 07.12.2019
Вы можете сделать это одним из двух способов. Во-первых, прямой способ — создать 2 столбца FlatList с гибкой компоновкой и распределить данные между ними следующим образом:
Предполагая, что вы определили style
и data
const style={
container: {
flex: 1,
flexDirection: 'row',
height: 400
},
column: {
flex: 1,
flexDirection: 'column'
},
row: {
flexDirection: 'row'
},
item: {
flex: 1
}
}
const data = [
{ key: 'A' },
{ key: 'B' },
{ key: 'C' },
{ key: 'D' },
{ key: 'E' },
{ key: 'F' },
{ key: 'G' },
{ key: 'H' },
{ key: 'I' }
];
Вы можете это сделать
render() {
//Split the data (however you want it)
const column1Data = data.filter((item, i) => i%2 === 0);
const column2Data = data.filter((item, i) => i%2 === 1);
return (
<View style={ style.container }>
<View style={ style.column }>
<Text>Column 1</Text>
<FlatList
data={ column1Data }
renderItem={ ({ item }) => (
<View style={ style.item }>
<Text>{ item.key }</Text>
</View>
) }
/>
</View>
<View style={ style.column }>
<Text>Column 2</Text>
<FlatList
data={ column2Data }
renderItem={ ({ item }) => (
<View style={ style.item }>
<Text>{ item.key }</Text>
</View>
) }
/>
</View>
</View>
);
}
Проблема заключается в том, что оба списка являются независимыми и будут плохо работать на мобильных устройствах. Лучшим способом было бы сгруппировать ваши данные и отобразить один столбец FlatList, чтобы ваш контент был унифицирован.
Во-первых, вам понадобится функция для группировки ваших данных в "строки" данных.
//The key here is grouping the data to be in one row together
const groupData = (items, groupLen) => {
const groups = [];
let i = 0;
while (i < items.length) {
groups.push(items.slice(i, i += groupLen));
}
return groups;
};
Тогда сделайте это...
render() {
const groupedItems = groupData(data, 2)
return (
<View style={ style.column }>
<Text>Main Column</Text>
<FlatList
data={ groupedItems }
renderItem={ ({ item }) => (
<View style={ style.row }>
{
/* item is really the group of items in the row */
item.map((singleItem, index ) => (
<Text style={ style.item }>{ singleItem.key }</Text>
))
}
</View>
) }
/>
</View>
);
}
Вам, вероятно, придется повозиться со стилем, чтобы получить его так, как вы хотите, но вы поняли идею :)
Мне потребовалось много времени, чтобы понять это, но на самом деле этого можно добиться без использования каких-либо внешних библиотек. Хитрость заключается в использовании отрицательной маржи.
Отрицательное поле будет применено к свойству VirtualizedList CellRendererComponent, чтобы заставить его правильно работать на Android.
JSX:
<View style={styles.container}>
<FlatList
style={styles.flatlist}
data={data}
keyExtractor={(item, index) => index.toString()}
CellRendererComponent={({ children, item, ...props }) => {
return (
<View {...props} style={{ marginTop: item.marginTop }}>
{children}
</View>
)
}}
renderItem={({ item }) => {
const { source: source1, height: height1, marginTop: marginTop1 } = item.image1;
const { source: source2, height: height2, marginTop: marginTop2 } = item.image2;
return (
<View style={Style.viewRow}>
<Image source={source1} style={[styles.image, { height: height1, marginTop: marginTop1 }]} />
<Image source={source2} style={[styles.image, { height: height2, marginTop: marginTop2 }]} />
</View>
)
}}
/>
</View>
Данные:
const source = { uri: 'https://placekitten.com/160/300' };
const data = [
{
marginTop: 0,
image1: { source, height: 300, marginTop: 0 },
image2: { source, height: 250, marginTop: 0 }
},
{
marginTop: -50,
image1: { source, height: 290, marginTop: 50 },
image2: { source, height: 300, marginTop: 0 }
},
{
marginTop: -40,
image1: { source, height: 250, marginTop: 40 },
image2: { source, height: 350, marginTop: 0 }
}
];
Стили:
const styles = StyleSheet.create({
container: {
flex: 1
},
flatList: {
width: '100%',
height: '100%'
},
viewRow: {
flexDirection: 'row'
},
image: {
width: '50%',
resizeMode: 'cover'
}
});
Обратите внимание, что правильное расположение изображений в массиве зависит от вас — всегда размещайте более высокое изображение на более короткой стороне и обязательно вычисляйте разницу высот и отслеживайте ее. Веселиться.
В react-native
стандартным стилем является flexDirection: 'col'
, что означает расположение элементов сверху вниз. Чтобы изменить это (справа налево), вы должны установить стиль на flexDirection: 'row'
.
<View style={{flexDirection: 'row'}}>
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
</View>
Пройти numColumns
<FlatList
data={albums}
renderItem={({item}) => <></>}
numColumns={2}
/>
вы можете попробовать с react-native-scroll-lazy
вместо ScrollView. Раньше у меня были проблемы, подобные описанным выше, я решил их и написал библиотеку, чтобы поделиться с людьми, у которых такая же проблема.