web-dev-qa-db-ja.com

React NativeのListViewグリッド

リモートJSONソースからリストを取得して画面に表示するReact Nativeのシンプルなアプリを構築しています。

これまでのところ、優れた example を使用して、行のListViewコンポーネントを使用して結果を表示することができました(つまり、行ごとに1つの結果、スクリーンショットを参照)。結果をグリッドに表示する必要があります。つまり、画面のサイズと向きに応じて、行ごとに3〜6項目です。

これらの結果をグリッドに入れる最良の方法は何ですか?これにListViewを使用できますか、それとも行ごとに1つの結果のみですか? flexboxスタイルで遊んでみましたが、Reactは%値を受け入れないようで、ListViewはスタイルを受け入れないため、まだ成功していません。

This is how my listings are displaying at the moment - one per row.

63
Mateo

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>}
        />
      );
    }
});

ダミーデータを含むListView。 contentContainerStyleの使用に注意してください。スタイルオブジェクトは次のとおりです。

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

コンテナに折り返し行のアイテムが必要であることを伝え、各子オブジェクトの幅を設定します。

Screenshot

125
Colin Ramsay

オーバーフローコメントがColin Ramsayの応答の下に隠されているため、これを回答として追加しています。React Native 0.28の時点で、リストビューのスタイリングにalignItems: 'flex-start',も必要です。これについてcodedump.ioのKerumenに感謝します。そう、

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

...残りはColinの応答と同様です。

35
kwishnu

ListViewが 非推奨 になりました。代わりに FlatList を使用してください。 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} />
  );
}

enter image description here

この ブログ投稿 は、FlatListの新機能を説明するのに適しています。

注:何らかの理由で、各アイテムの通常のkeyExtractorプロップではなく、FlatListでkeyを使用する必要があります。そうしないと、警告が表示されます。 基本的なFlatListコードは警告をスローします-React Native

34
Tim Perkins

私は同じ問題を抱えていたので、その問題を解決するコンポーネントを作成しました。ここで見つけることができます: https://github.com/pavlelekic/react-native-gridview

また、このコンポーネントが行うもう1つのことは、アイテムの幅が整数であることを確認することです。これにより、アイテムの境界線にアンチエイリアスが適用されず、鮮明で鮮明になります。

7
Pavle Lekic

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,
  },
});
5
Yi Feng Xie

反応ネイティブでListviewの代わりにFlatListを使用します。付加価値の高い機能とパフォーマンスの向上があります。 こちらの例をご覧ください

2
Moorthy

FlatListを使用し、numColumnsを設定して、グリッドと同じ結果を取得できます。

1
nguyencse

優れたパフォーマンスで無限スクロールをサポートするには、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>
  )
}    

例は次のようになります

enter image description here

敬具、ニコルズ

0
jdnichollsc