# ListView

{% hint style="danger" %}
建議使用FlatList
{% endhint %}

[官方文檔](https://facebook.github.io/react-native/docs/listview.html)    [中文](https://reactnative.cn/docs/0.44/listview.html#content)    [React Native Express](http://www.reactnativeexpress.com/listview)

* DataSource

  > 用於為ListView指定當前的數據源要更新的數據源中的數據，請（每次都重新）調用cloneWithRows方法（如果用到了section，則對應cloneWithRowsAndSections方法） 數據源中的數據本身是不可修改的，所以請勿直接嘗試修改 clone方法會自動提取新數據並進行逐行對比（使用rowHasChanged方法中的策略），這樣的ListView就知道哪些行需要重新渲染了!!
* rowHasChanged

  > 此函數告訴ListView它是否需要重新繪製一行數據
* cloneWithRows

  > 接收一個數組，根據該數組創建接收一個數組，根據該數組創建數據源
* renderRow

  > 標示ListView中每一行需要顯示的樣子 參數表示當前需要顯示的數據

<br>

### Sample Code

![](https://bambooooo.gitbooks.io/react-native/content/React%20Native/images/basic/listview/listview1.png)

```
import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
} from 'react-native';

export default class ListView1Demo extends Component {
  constructor(props){
    super(props)
    // 創建dataSource對象，判斷row更新與否
    var ds = new ListView.DataSource({
      rowHasChanged:(r1, r2) => r1 !== r2
    })
    //初始化dataSource，後面建構listview的時候需要用到。
    this.state = {
      dataSource: ds
    }
  }

  //在render方法裡面建構listview
  render() {
    return (
      <View style={styles.container}>
        <ListView
          //设置datasource
          dataSource = {this.state.dataSource.cloneWithRows(this.generateRowData())}

          //渲染row
          renderRow = {(rowData) => <Text>{rowData}</Text> }
        />
      </View>
    );
  }

  //產生listview內的資料
  generateRowData() {
    var data = [];
    for (var i = 0; i < 100; i++) {
      var text = "this is item :" +i;
      data.push(text);
    }
    return data;
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 30,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});
```

### &#x20;Section Sample

![](https://bambooooo.gitbooks.io/react-native/content/React%20Native/images/basic/listview/listview2.png)

```
import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
} from 'react-native';

export default class SectionListViewDemo extends Component {
  constructor(props){
    super(props)
    var ds = new ListView.DataSource({
      //創建dataSource對象，判斷row更新與否
      rowHasChanged:(r1, r2) => r1 !== r2,
      //更新section的規則
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
    })

    this.state = {
      sectionHeader: 'Hello',
      dataSource: ds,
      //這裡使用了字典的方式，那麼會自動將字典的key作為section的部分顯示出來
      data: {a:this.generateRowData('a'), b:['l', 'f', 'b1', 'b2'], c:['c', 'cd1', 'c2', 'c3'], d:['l', 'i'], e:this.generateRowData('e')}
    }
  }

renderRow(rowData, rowId, sectionId) {
  return (
    <Text>{`${rowData}, index of section:${sectionId}`}</Text>
  );
}
  //然后在render方法里面构建listview
  render() {
    return (
      <View style={styles.container}>
         <Text style={styles.header}>{this.state.sectionHeader}</Text> 

        <ListView
          //设置datasource
          dataSource = {this.state.dataSource.cloneWithRowsAndSections(this.state.data)}
          //下方是 指定section
          //dataSource = {this.state.dataSource.cloneWithRowsAndSections(this.state.data, ['a'])}

          //section Header. but ios & android something Differences
          renderSectionHeader={(sectionData,sectionID)=>  
            <View style={styles.section}><Text>{sectionID}</Text></View>}

          //renderRow方法的參數默認按照順序如下 (rowData, sectionID, rowID, highlightRow)
          renderRow = {(rowData, sectionId, rowId) => 
            this.renderRow( rowData, sectionId, rowId)}
        />
      </View>
    );
  }

  //產生listview內的資料
  generateRowData(sectionName) {
    var data = [];
    for (var i = 0; i < 25; i++) {
      var text = `${sectionName} - ${i}`;
      data.push(text);
    }
    return data;
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 30,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  section: {
    alignItems: 'center',
    backgroundColor: 'skyblue'
  },
  header: {
    // position: 'absolute',
    // top: 0,
    // zIndex: 1,
  }
});
```

### &#x20;參考

* [react native組件學習之listivew](http://blog.csdn.net/mockingbirds/article/details/50532855) - mockingbirds
* &#x20;[ReactNative之ListView學習總結（二）帶有section的demo](http://blog.csdn.net/binglan520/article/details/70738748)
* [React Native學習ListView（三）：吸頂效果](http://lib.csdn.net/article/reactnative/68067)&#x20;
* [React Native ListView with Section Headers](https://moduscreate.com/blog/react-native-listview-with-section-headers/)
* <http://blog.csdn.net/sinat_17775997/article/details/73822920>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://twins-bamboo.gitbook.io/react-native-note/basic/listview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
