反应本机 FlatList 与列,最后一项宽度
React Native FlatList with columns, Last item width
我正在使用 FlatList 在两列中显示项目列表
<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}/> }
/>
卡片组件只是一个带有一些样式的视图:
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130}} ></View>
它工作正常,但如果项目的数量是奇数,最后一行只包含一个项目并且该项目延伸到屏幕的整个宽度。
如何将项目设置为与其他项目相同的宽度?
您可以在此处尝试一些操作。
A) 为卡片设置预定义的宽度(可能等于您设置的高度?)。然后,您可以使用 alignItems
将卡片放置在中间或左侧 - 不确定您在这里想要哪个。
B) 如果有偶数张卡片,您可以在末尾添加一个空视图以填充此 space。我发现此方法非常笨拙,但在尝试为将来的元素保留 space 时很有用。
C) 只需使用 alignItems: 'space-between
,我喜欢用它来居中项目,但你必须定义宽度,或者使用类似 flex:0.5
的东西
我建议对 flexbox 进行更多研究以帮助您解决这个问题,因为很难说出这种情况的上下文。我假设上述方法会有所帮助,但如果没有,这里有一些链接供您查看 -
Third linkLink破
希望这对您有所帮助。如果您需要任何进一步的说明 - 请询问
您可以尝试通过 Dimensions 获取设备的当前宽度,根据您要呈现的列数进行一些计算,减去边距并将其设置为 minWidth 和 maxWidth。
例如:
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>
对于你的情况使用 flex: 1/2
因此:您的 item 应该有 flex of 1/(number of columns) 如果你有 3 列你的项目应该有 flex:1/3
原因是你的 Card 有样式 flex: 1
,所以它会尝试扩展所有 space 的剩余部分。
您可以通过将 maxWidth: '50%'
添加到您的 Card style
来修复它
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>
这是使用列和均匀间隔设置 FlatList
样式的最干净的方法:
<FlatList style={{margin:5}}
numColumns={2} // set number of columns
columnWrapperStyle={style.row} // space them out evenly
data={this.state.items}
keyExtractor={(item, index) => item.id }
renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>
const style = StyleSheet.create({
row: {
flex: 1,
justifyContent: "space-around"
}
});
@Emilius Mfuruki 的建议很好,但如果您的文本长度不同,则效果不佳。然后在项目视图中使用此宽度:
const {height, width} = Dimensions.get('window');
const itemWidth = (width - (MarginFromTheSide * 2 + MarginInBetween * (n-1))) / n;
在 FlatList 中使用:
columnWrapperStyle={{
flex: 1,
justifyContent: 'space-evenly',
}}
完美运行。
您可以使用 ListFooterComponent={this.renderFooter}
只需使用 flex:0.5 和宽度:'50%'
创建一个包含奇数张图片的数组,例如:
const images = [
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
];
然后,使用下面给出的代码,
const App = () => {
const _renderItem = ({ item, index }) => (
<Image
source={item}
style={{
width: '50%',
height: 200,
}}
resizeMode="cover"
/>
);
return (
<View style={{flex: 1, marginHorizontal: 10,}}>
<FlatList
columnWrapperStyle={{ justifyContent: 'space-between' }}
keyExtractor={(_, index)=> index.toString()}
data={images}
numColumns={2}
renderItem={_renderItem}
/>
</View>
)
};
export default App;
我尝试了上面的一些解决方案,但最后一项(2 列列表)的边距仍然存在一些问题。
我的解决方案是简单地将项目包装到父容器中,将原始容器保留为 flex: 1
,将项目的父容器保留为 flex: 0.5
,这样它就会正确地占用边距。
itemContainer: {
flex: 0.5,
},
itemSubContainer: {
flex: 1,
marginHorizontal: margin,
},
最简单的解决方案是计算一下。
想象一下,我们每行有 2 个视图,我们想给每边 10 个边距,它看起来像这样:
如上图所示,每个视图在水平方向上都有 2 个边距。 (红色矩形内)
所以我们必须从宽度中减去边距、列数和 2 的乘积。
import { Dimensions } from 'react-native';
const {width} = Dimensions.get("window")
const column = 2
const margin = 10
const SIZE = (width - (margin * column * 2)) / column
<View style={{ margin: 10, width: SIZE }} ></View>
我也遇到了同样的问题
所以,你可以使用这个 package。
默认情况下可以防止那个问题和其他一些问题。
安装:
npm install grid-flatlist-react-native
用法:
import GridFlatList from 'grid-flatlist-react-native';
<GridFlatList
data={[1,2,3,4,5,6]}
renderItem={(item) => (<Text>{item}</Text>)}
gap={10} // spacing between items
paddingHorizontal={10} // shadow around elements will not be clipped
/>
我正在使用 FlatList 在两列中显示项目列表
<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}/> }
/>
卡片组件只是一个带有一些样式的视图:
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130}} ></View>
它工作正常,但如果项目的数量是奇数,最后一行只包含一个项目并且该项目延伸到屏幕的整个宽度。
如何将项目设置为与其他项目相同的宽度?
您可以在此处尝试一些操作。
A) 为卡片设置预定义的宽度(可能等于您设置的高度?)。然后,您可以使用 alignItems
将卡片放置在中间或左侧 - 不确定您在这里想要哪个。
B) 如果有偶数张卡片,您可以在末尾添加一个空视图以填充此 space。我发现此方法非常笨拙,但在尝试为将来的元素保留 space 时很有用。
C) 只需使用 alignItems: 'space-between
,我喜欢用它来居中项目,但你必须定义宽度,或者使用类似 flex:0.5
我建议对 flexbox 进行更多研究以帮助您解决这个问题,因为很难说出这种情况的上下文。我假设上述方法会有所帮助,但如果没有,这里有一些链接供您查看 -
Third linkLink破
希望这对您有所帮助。如果您需要任何进一步的说明 - 请询问
您可以尝试通过 Dimensions 获取设备的当前宽度,根据您要呈现的列数进行一些计算,减去边距并将其设置为 minWidth 和 maxWidth。
例如:
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>
对于你的情况使用 flex: 1/2
因此:您的 item 应该有 flex of 1/(number of columns) 如果你有 3 列你的项目应该有 flex:1/3
原因是你的 Card 有样式 flex: 1
,所以它会尝试扩展所有 space 的剩余部分。
您可以通过将 maxWidth: '50%'
添加到您的 Card style
<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>
这是使用列和均匀间隔设置 FlatList
样式的最干净的方法:
<FlatList style={{margin:5}}
numColumns={2} // set number of columns
columnWrapperStyle={style.row} // space them out evenly
data={this.state.items}
keyExtractor={(item, index) => item.id }
renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>
const style = StyleSheet.create({
row: {
flex: 1,
justifyContent: "space-around"
}
});
@Emilius Mfuruki 的建议很好,但如果您的文本长度不同,则效果不佳。然后在项目视图中使用此宽度:
const {height, width} = Dimensions.get('window');
const itemWidth = (width - (MarginFromTheSide * 2 + MarginInBetween * (n-1))) / n;
在 FlatList 中使用:
columnWrapperStyle={{
flex: 1,
justifyContent: 'space-evenly',
}}
完美运行。
您可以使用 ListFooterComponent={this.renderFooter}
只需使用 flex:0.5 和宽度:'50%'
创建一个包含奇数张图片的数组,例如:
const images = [
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
require('./../...jpg'),
];
然后,使用下面给出的代码,
const App = () => {
const _renderItem = ({ item, index }) => (
<Image
source={item}
style={{
width: '50%',
height: 200,
}}
resizeMode="cover"
/>
);
return (
<View style={{flex: 1, marginHorizontal: 10,}}>
<FlatList
columnWrapperStyle={{ justifyContent: 'space-between' }}
keyExtractor={(_, index)=> index.toString()}
data={images}
numColumns={2}
renderItem={_renderItem}
/>
</View>
)
};
export default App;
我尝试了上面的一些解决方案,但最后一项(2 列列表)的边距仍然存在一些问题。
我的解决方案是简单地将项目包装到父容器中,将原始容器保留为 flex: 1
,将项目的父容器保留为 flex: 0.5
,这样它就会正确地占用边距。
itemContainer: {
flex: 0.5,
},
itemSubContainer: {
flex: 1,
marginHorizontal: margin,
},
最简单的解决方案是计算一下。 想象一下,我们每行有 2 个视图,我们想给每边 10 个边距,它看起来像这样:
如上图所示,每个视图在水平方向上都有 2 个边距。 (红色矩形内) 所以我们必须从宽度中减去边距、列数和 2 的乘积。
import { Dimensions } from 'react-native';
const {width} = Dimensions.get("window")
const column = 2
const margin = 10
const SIZE = (width - (margin * column * 2)) / column
<View style={{ margin: 10, width: SIZE }} ></View>
我也遇到了同样的问题
所以,你可以使用这个 package。
默认情况下可以防止那个问题和其他一些问题。
安装:
npm install grid-flatlist-react-native
用法:
import GridFlatList from 'grid-flatlist-react-native';
<GridFlatList
data={[1,2,3,4,5,6]}
renderItem={(item) => (<Text>{item}</Text>)}
gap={10} // spacing between items
paddingHorizontal={10} // shadow around elements will not be clipped
/>