React Native中的ListView网格

React Native中的ListView网格,listview,react-native,Listview,React Native,我正在React Native中构建一个简单的应用程序,从远程JSON源获取列表并在屏幕上显示 到目前为止,使用这里的优秀工具,我成功地获得了使用ListView组件以行显示的结果(即每行1个结果,请参见屏幕截图)。我需要在网格中显示结果,即每行3到6个项目,具体取决于屏幕大小和方向 将这些结果放入网格的最佳方式是什么?我可以使用ListView进行此操作,还是仅对每行一个结果使用ListView?我尝试过使用flexbox样式,但由于React似乎不接受%值,ListView也不接受样式,所以

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

到目前为止,使用这里的优秀工具,我成功地获得了使用ListView组件以行显示的结果(即每行1个结果,请参见屏幕截图)。我需要在网格中显示结果,即每行3到6个项目,具体取决于屏幕大小和方向

将这些结果放入网格的最佳方式是什么?我可以使用ListView进行此操作,还是仅对每行一个结果使用ListView?我尝试过使用flexbox样式,但由于React似乎不接受%值,ListView也不接受样式,所以我还没有取得任何成功


您需要结合使用ListView包装ScrollView的知识,并利用其属性。记住这一点,您可以使用ScrollView的
contentContainerStyle
prop设置项目的样式

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>}
        />
      );
    }
});
我们告诉容器我们想要包装行中的项目,然后设置每个子对象的宽度


我之所以添加这个作为答案,是因为溢出注释隐藏在Colin Ramsay的响应下:从React Native 0.28开始,您还需要在listview样式中使用
alignItems:“flex start”,
,否则flexWrap将无法工作。感谢codedump.io上的Kerumen。所以

var styles = StyleSheet.create({
list: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    alignItems: 'flex-start',
},

…其余部分如科林的回答。

按照科林·拉姆齐的回答。如果你想让每件物品都有一半的宽度,试试这个方法

...
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,
  },
});

我也有同样的问题,我写了一个组件来解决这个问题,你可以在这里找到它:


此外,该组件所做的另一件事是确保项目宽度是一个整数,以便项目的边界没有抗锯齿,它们清晰明了。

在react native中使用FlatList而不是Listview。它有更多的增值功能和更好的性能

ListView现在是,您应该改用它。FlatList有一个名为
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} />
  );
}
const数据=[
{id:'a',value:'a'},
{id:'b',value:'b'},
{id:'c',value:'c'},
{id:'d',value:'d'},
{id:'e',value:'e'},
{id:'f',value:'f'},
];
常数numColumns=3;
const size=Dimensions.get('window')。宽度/numColumns;
const styles=StyleSheet.create({
itemContainer:{
宽度:大小,
高度:尺寸,
},
项目:{
弹性:1,
差额:3,
背景颜色:“浅蓝色”,
}
});
功能网格(道具){
返回(
(
{item.value}
)}
keyExtractor={item=>item.id}
numColumns={numColumns}/>
);
}

这很好地解释了FlatList的新特性


注意:由于某些原因,您必须在平面列表上使用
keydractor
,而不是在每个项目上使用典型的
key
道具。否则你会得到警告

您可以使用FlatList并设置numColumns来获得与grid相同的结果

使用React NativeFlatList组件检查以下示例,以支持性能优异的无限滚动:

//Resize the grid
onLayout = (event) => { 
  const {width} = event.nativeEvent.layout;
  const itemWidth = 150
  const numColumns = Math.floor(width/itemWidth)
  this.setState({ numColumns: numColumns })
}

render() {
  return (
    <Content 
     contentContainerStyle={{flex:1, alignItems: 'center'}}
     onLayout={this.onLayout}>
       <FlatList
        data={this.state.products}
        keyExtractor={(item, index) => index}
        key={this.state.numColumns}
        numColumns={this.state.numColumns}
        renderItem={({item}) => 
          <ListThumb //Custom component, it's only an example.
           navigation={navigation}
           brand={item.brand}
           price={item.price}
           imageSource={item.image_link}/>
        }
     />
   </Content>
  )
}    
//调整网格大小
onLayout=(事件)=>{
const{width}=event.nativeEvent.layout;
const itemWidth=150
常量numColumns=数学楼层(宽度/项目宽度)
this.setState({numColumns:numColumns})
}
render(){
返回(
索引}
key={this.state.numColumns}
numColumns={this.state.numColumns}
renderItem={({item})=>

ScrollView带有contentContainerStyle道具的

        <ScrollView contentContainerStyle={{ flexDirection: "row", flexWrap: "wrap", alignContent: "center",}}>
            {user.posts.map((post, index) => (
                <Image
                    source={require(post.uri)}
                    key={index}
                    style={{ width: 100, height: 100 }}
                />
            ))}
        </ScrollView>

{user.posts.map((post,index)=>(
))}

这正是我正在寻找的东西!谢谢!谢谢!这正是我所希望的,但我认为不存在的东西。这里有人知道在使用
ListView
分区时如何做到这一点吗?如何使每个子对象的宽度等于父容器的一半(对于每行两个大小相等的孩子)?我尝试了flex:.5对于使用flex的孩子:1对于父listview,它失败了。对于不同的高度工作?看起来像pinterest?这是一个非常重要的评论。谢谢:)@kwishnu你是上帝!我没有在codedump上回答。这是在StackOverflow上;)@kerumen-真的!不知怎么的,这个问题最终在我找到它的地方结束了……无论如何,谢谢你!它帮助了很多人,我把你的票投了上去answers@kwishnu你是我在这里结结巴巴地回答你之前很久弄得最棒的。非常感谢你的回答!@Pavle Lekic,谢谢你写了这个库。我补充道一个关于renderHeader的问题,它的大小没有达到全宽。
        <ScrollView contentContainerStyle={{ flexDirection: "row", flexWrap: "wrap", alignContent: "center",}}>
            {user.posts.map((post, index) => (
                <Image
                    source={require(post.uri)}
                    key={index}
                    style={{ width: 100, height: 100 }}
                />
            ))}
        </ScrollView>