基礎篇章:關于 React Native 之 ListView 組件的講解

我們講完ScrollView組件,其實順其自然的就應該講解ListView,對于前段和移動端的開發人員應該非常熟悉這樣的控件吧,具體是做什么的,我感覺不用我講了吧。我們來看看它怎么使用吧。

大家好,我是ListView,我是React Native大家族中基礎組件中,一個核心組件。我可以高效的展示垂直滾動的變化的數據列表,而且這個列表有一個特點就是結構和數據比較相似才可以哦。

我和ScrollView那家伙不太相同,我更適于長列表數據,且元素個數可以增刪。和ScrollView不同的是,我并不立即渲染所有元素,而是優先渲染屏幕上可見的元素。怎么樣?是不是感覺我更聰明?

我有兩個必須的屬性是dataSource和renderRow。dataSource是列表的數據源,而renderRow則逐個解析數據源中的數據,然后返回一個設定好格式的組件來渲染。舉個例子:我最基本的使用方式就是創建一個ListView.DataSource數據源,然后給它傳遞一個普通的數據數組,再使用數據源來實例化一個ListView組件,并且定義它的renderRow回調函數,這個函數會接受數組中的每個數據作為參數,返回一個可渲染的組件(作為我的每一行)。

記住:rowHasChanged函數也是我的必需屬性。用于比較兩行數據是否是同一個數據來判斷某行數據是否變化了。

官方簡單例子

class MyComponent extends Component {
  constructor() {
    super();
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows(['row 1', 'row 2']),
    };
  }

  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={(rowData) => <Text>{rowData}</Text>}
      />
    );
  }
}

高級屬性

想我這么聰明的組件,我當然還支持一些高級的特性,比如:給每組數組加一個粘節標題,也就是類似于通訊錄中其首字母會在滑動過程中吸附在屏幕上方,支持頁眉和頁腳,也就是可以在列表中添加頭部和尾部。在到達列表尾部的時候調用回調函數(onEndReached),還有在視野內可見的數據變化時調用回調函數(onChangeVisibleRows),以及一些性能方面的優化。

在我母親制定的官方介紹中,這么說:有一些性能優化使得我ListView可以滾動的更加平滑,尤其是在動態加載可能很大(或者概念上無限長的)數據集的時候:

  • 只更新變化的行 - 提供了rowHasChanged函數可以告訴ListView它是否需要重繪一行數據。
  • 限制頻率的行渲染 - 默認情況下,每次消息循環只有一行會被渲染(可以用pageSize屬性配置)。這把較大的工作分散成小的碎片,以降低因為渲染而導致丟幀的可能性。

基本屬性

介紹完我的高級功能特性,再來看看我的基本屬性吧,懂了這些,你可以玩我跟玩孩子似的,運用自如。

我前面說了,我這人比ScrollView那家伙聰明多了,所以它的屬性,我都能用,這里關于和ScrollView相同的屬性就不贅述了。看看我的與眾不同,比它聰明在哪吧?

  • dataSource 傳入的數據源
  • enableEmptySections bool 空內容的sections是否被渲染,默認是會渲染
  • initialListSize number 指定在組件剛掛載的時候渲染多少行數據。用這個屬性來確保首屏顯示合適數量的數據,而不是花費太多幀逐步顯示出來。
  • onChangeVisibleRows function 當可見的行發生變化的時候回調該函數。visibleRows參數對所有可見的行為{selectionID:{rowId:true}}的形式,changedRow參數對已經改變可見的行為{selectionID:{rowID:true|false}}。該值true代表可見,false代表在視圖之外不可見的行。
  • onEndReached function 當所有的數據都已經渲染過,并且列表被滾動到距離最底部不足onEndReachedThreshold個像素的距離時調用。原生的滾動事件會被作為參數傳遞。譯注:當第一次渲染時,如果數據不足一屏(比如初始值是空的),這個事件也會被觸發。
  • onEndReachedThreshold number 調用onEndReached之前的臨界值,單位是像素。
  • pageSize number 每一次事件的循環渲染的行數。
  • removeClippedSubviews bool 用于提升大列表的滾動性能。需要給行容器添加樣式overflow:’hidden’。(Android已默認添加此樣式)。此屬性默認開啟。
  • renderFooter function 方法 ()=>renderable ,在每次渲染過程中頭和尾總會重新進行渲染。如果發現該重新繪制的性能開銷比較大的時候,可以使用StaticContainer容器或者其他合適的組件。在每一次渲染過程中Footer(尾)該會一直在列表的底部,header(頭)該會一直在列表的頭部
  • renderHeader function 與上同理
  • renderRow function (rowData, sectionID, rowID, highlightRow) => renderable 從數據源(Data source)中接受一條數據,以及它和它所在section的ID。返回一個可渲染的組件來為這行數據進行渲染。默認情況下參數中的數據就是放進數據源中的數據本身,不過也可以提供一些轉換器。如果某一行正在被高亮(通過調用highlightRow函數),ListView會得到相應的通知。當一行被高亮時,其兩側的分割線會被隱藏。行的高亮狀態可以通過調用highlightRow(null)來重置。
  • renderScrollComponent function 返回在列表行呈現的滾動組件的功能。默認為ScrollView。
  • renderSectionHeader function (sectionData, sectionID) => renderable 如果提供了此函數,會為每個小節(section)渲染一個粘性的標題。粘性是指當它剛出現時,會處在對應小節的內容頂部;繼續下滑當它到達屏幕頂端的時候,它會停留在屏幕頂端,一直到對應的位置被下一個小節的標題占據為止。
  • renderSeparator function 如果提供了此屬性,一個可渲染的組件會被渲染在每一行下面,除了小節標題的前面的最后一行。在其上方的小節ID和行ID,以及鄰近的行是否被高亮會作為參數傳遞進來。
  • scrollRenderAheadDistance number 當該行進入屏幕多少像素以內之后就開始渲染該行
  • stickyHeaderIndices [number] ios獨有 一個子視圖下標的數組,用于決定哪些成員會在滾動之后固定在屏幕頂端。

實例演示

效果圖

來,看看我美不美,好不好用,我的真實面目如下:

代碼

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

class ListViewDemo extends Component {
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows(this._genRows(-1))
    };
  }

  _genRows(flag){
        const dataBlob = [];
        for(let i = 0 ; i< 88 ; i ++ ){
          if(i == flag){
            dataBlob.push("非著名程序員+我被打了"+i);
          }else{
             dataBlob.push("非著名程序員"+i);
          }
        }
        return dataBlob;
    }

  render() {
    return (
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this._renderRow.bind(this)}
        />

    );
  }

  _renderRow (rowData,sectionID, rowID) {
    return (
        <TouchableHighlight onPress={() => {
          this._pressRow(rowData,rowID);
        }}
        underlayColor='red'
        >
          <View>
            <View style={styles.row}>
              <Image style={{width:40,height:40}} source={require('./Thumbnails/head.jpg')}/>
              <Text style={{flex:1,fontSize:20,marginLeft:20}}>
                {rowData}
              </Text>
            </View>
          </View>
        </TouchableHighlight>
    );
   }

  _pressRow(rowData,rowID){
        alert(rowData);
        this.setState({dataSource: this.state.dataSource.cloneWithRows(
        this._genRows(rowID)
    )});
    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  row: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems:'center',
    padding: 10,
  },
});

AppRegistry.registerComponent('ListViewDemo', () => ListViewDemo);

ok,關于ListView組件的講解大概就先講到這里,更多的內容和實例,歡迎大家移步到官網,看文檔,但是官網上大部分的例子用的是es5的語法。

 

 

來自:http://godcoder.me/2016/11/02/基礎篇章:關于 React Native 之 ListView 組件的講解/

 

 本文由用戶 RoseannaFor 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!