React Native中的ListView网格

Mat*_*teo 63 listview react-native

我正在React Native中构建一个简单的应用程序,它从远程JSON源获取列表并在屏幕上显示它们.

到目前为止,使用这里的优秀示例,我已经设法使用行中的ListView组件显示结果(即每行1个结果,请参见屏幕截图).我需要将结果显示在网格中,即每行3到6个项目,具体取决于屏幕大小和方向.

将这些结果导入网格的最佳方法是什么?我可以使用ListView,还是仅用于每行一次的结果?我尝试过使用flexbox样式但是,由于React似乎不接受%值而ListView不接受样式,我还没有取得任何成功.

这就是我的列表当前显示的方式 - 每行一个.

Col*_*say 125

您需要使用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>}
        />
      );
    }
});
Run Code Online (Sandbox Code Playgroud)

只是一个带有一些虚拟数据的ListView.注意使用contentContainerStyle.这是样式对象:

var styles = StyleSheet.create({
    list: {
        flexDirection: 'row',
        flexWrap: 'wrap'
    },
    item: {
        backgroundColor: 'red',
        margin: 3,
        width: 100
    }
});
Run Code Online (Sandbox Code Playgroud)

我们告诉容器我们想要包装行中的项目,我们设置每个子对象的宽度.

截图

  • 当使用带有部分的`ListView`时,这里的任何人都知道如何使这个工作吗? (5认同)

kwi*_*hnu 35

我添加这个作为答案,因为溢出的评论隐藏在Colin Ramsay的回复中:从React Native 0.28开始,你还需要alignItems: 'flex-start',在listview样式中或者flexWrap不起作用.感谢codump.io上的Kerumen.所以,

var styles = StyleSheet.create({
list: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    alignItems: 'flex-start',
},
Run Code Online (Sandbox Code Playgroud)

......其余的和科林的回答一样.

  • 这是一个如此重要的评论.谢谢 :) (3认同)

Tim*_*ins 35

ListView现已弃用,您应该使用FlatList.FlatList有一个prop 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} />
  );
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这篇博客文章很好地解释了FlatList的新功能.

注意:出于某种原因,您必须使用keyExtractorFlatList而不是key每个项目上的典型prop.否则你会收到警告.基本FlatList代码抛出警告 - React Native


Pav*_*kic 7

我有同样的问题,我写了一个解决这个问题的组件,你可以在这里找到它:https://github.com/pavlelekic/react-native-gridview

此外,该组件所做的另一件事是它确保项目宽度是一个整数,因此项目的边框没有抗锯齿,它们清晰明快.


Yi *_*Xie 5

关注Colin Ramsay的回答.如果你想要每个项目的半宽,试试这种方式.

...
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,
  },
});
Run Code Online (Sandbox Code Playgroud)