用列反应Native FlatList,最后一项宽度


76

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

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

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

在此处输入图片说明

Answers:


35

您可以在这里尝试一些操作。

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

B)如果卡片数量为偶数,则可以在末尾添加一个空白的“视图”以填充此空间。我发现此方法很笨拙,但在尝试为将来的元素留出空间时很有用。

C)只需使用alignItems: 'space-between,我喜欢用它来使项目居中,但您必须定义宽度,或使用类似flex:0.5

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

第一个连结

第二个环节

第三环节 链接断开

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


1
B是一个合理的技巧。选项A是多余的,可以通过添加flexWrap使其简单地设置为对齐。在这种情况下,numColumns的目的是什么?
伊甸园

我不愿意使用B,但是我做到了,尽管它是个技巧,但效果很好,我不必指定元素的宽度(我希望它们调整为可用的宽度)
Escobar5

@Ryan:我想要第一个单元格完全拉伸并有3列,我该怎么办?
阿比舍克

选项C:设置Flex:0.5对我有用。
阿曼·戈亚尔

46

您的情况下使用flex:1/2

因此:你的项目应该有弹性的1 /(列数),如果你有3列的项目应具有弹性:1/3


2
不知道为什么没有将此标记为答案。这是最简单正确的解决方案!
tnort173

9
当我给出flex:1/2时,最后一个项目的宽度大于以前的项目,请问如何解决这个问题
iOSDev

天才!!!这有效!有史以来最好的解决方法。谢谢你,你应该得到正确的答案
msqar

我已经尝试过了,就像“ iOSDev”所说的那样,最后一行的单个项目比上一行的第一个项目稍宽。因此,此解决方案对我不起作用
se22as

@ tnort173,因为这不起作用;最后一项仍然比其他项大。
Abdul Sadik Yalcin

18

您可以尝试通过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奇数列的情况
Arnaud Moret

非常好。谢谢!
马克

收到错误消息:属性“样式”的类型不兼容
Ghost

@Ghost您在使用Typescript吗?如果是这样,那么该错误可能与Typescript有关
skyplor

10

这是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"
        }
    });

6

原因是您的Card具有样式flex: 1,因此它将尝试扩大所有剩余的空间。您可以通过添加maxWidth: '50%'卡片样式来修复它

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>

有史以来最简单的解决方案
Muhammad Ashfaq

0

@Emilius Mfuruki的建议很好。但是,如果文本的长度不同,则无法正常工作。

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

在视图内部使用此宽度。

在FlatList中,使用columnWrapperStyle = {{flex:1,justifyContent:'space-evenly',}}

完美运作。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.