93

我正在使用 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>

它工作正常,但如果项目数是奇数,最后一行只包含一个项目,并且该项目延伸到屏幕的整个宽度。

如何将项目设置为与其他项目相同的宽度?

在此处输入图像描述

4

12 回答 12

75

对于您的情况,请使用flex: 1/2

因此:如果您有 3 列,则您的项目应具有1/(列数)的 flex,您的项目应具有 flex: 1/3

于 2018-11-06T16:11:47.637 回答
41

您可以在这里尝试一些事情。

A)为卡片设置一个预定义的宽度(也许等于你设置的高度?)。然后您可以使用alignItems以便将卡放置在中间或左侧 - 不确定您想要的位置。

B)如果有偶数张卡片,您可以在最后添加一个空视图以填充此空间。我发现这种方法非常笨拙,但在尝试为未来元素留出空间时很有用。

C)简单地使用alignItems: 'space-between,我喜欢用它来居中项目,但你必须定义宽度,或者使用类似的东西flex:0.5

我建议对 flexbox 进行更多研究以帮助您解决此问题,因为很难说出这种情况的上下文。我假设上述方法会有所帮助,但如果没有,这里有一些链接供您查看 -

第一个链接

第二个链接

第三个链接 链接断开

希望这可以帮助。如果您需要任何进一步的说明 - 只要问

于 2017-04-26T08:00:38.290 回答
20

您可以尝试通过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>
于 2017-07-13T15:22:56.900 回答
18

这是FlatList使用列和均匀间隔设置 a 样式的最简洁方法:

    <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"
        }
    });
于 2019-05-06T05:16:48.383 回答
7

原因是你的卡片有风格flex: 1,所以它会尝试扩展所有剩余的空间。maxWidth: '50%'您可以通过添加到您的卡片样式来修复它

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>
于 2019-01-17T05:22:55.553 回答
5

@Emilius Mfuruki 的建议很好,但是如果您有不同长度的文本,它就不能完美地工作。然后在您的项目视图中使用此宽度:

const {height, width} = Dimensions.get('window');
const itemWidth = (width - (MarginFromTheSide * 2 + MarginInBetween * (n-1))) / n;

在 FlatList 中使用:

columnWrapperStyle={{
            flex: 1,
            justifyContent: 'space-evenly',
          }}

完美运行。

于 2020-05-03T11:42:09.067 回答
1

我尝试了上面的一些解决方案,但最后一项(2 列列表)的边距仍然存在一些问题。

在此处输入图像描述

我的解决方案只是将项目包装到父容器中,将原始容器与项目的父容器一起保留flex: 1flex: 0.5以便正确占用边距。

itemContainer: {
  flex: 0.5,
},
itemSubContainer: {
  flex: 1,
  marginHorizontal: margin,
},
于 2021-12-16T15:42:33.203 回答
0

最简单的解决方案是做数学。想象一下,我们每行有 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>
于 2022-01-28T14:56:47.343 回答
0

您可以使用 ListFooterComponent={this.renderFooter}

于 2020-09-24T20:49:15.017 回答
0

只需使用 flex:0.5 和 width:'50%'

于 2020-11-06T17:43:31.727 回答
0

创建一个包含奇数个图像的数组,例如:

const images = [
  require('./../...jpg'),
  require('./../...jpg'),
  require('./../...jpg'),
  require('./../...jpg'),
  require('./../...jpg'),
];

然后,使用下面给出的代码,

const App = () => {
const _renderItem = ({ item, index }) => (
  <Image
    source={item}
    style={{
      width:
        images.length % 2 !== 0 && images.length - 1 === index
          ? '100%'
          : '50%',
      height: 200,
    }}
    resizeMode="cover"
  />
 );

return (
    <View style={{flex: 1, marginHorizontal: 10,}}>
      <FlatList
        columnWrapperStyle={{ justifyContent: 'space-between' }}
        data={images}
        numColumns={2}
        renderItem={_renderItem}
      />
    </View>
  )
};
export default App;

工作示例

于 2021-04-22T10:30:22.857 回答
0

我也面临同样的问题。

所以,你可以只使用这个

默认情况下,它可以防止该问题和其他一些问题。

安装:

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
/>
于 2022-02-21T10:56:24.540 回答