列表視圖

2019-08-14 14:25 更新

列表視圖——為變化的數(shù)據(jù)列表的垂直滾動(dòng)的高效顯示而設(shè)計(jì)的一個(gè)核心組件。最小的 API 是創(chuàng)建一個(gè)ListView.DataSource,用一個(gè)簡(jiǎn)單的數(shù)組數(shù)據(jù)的 blob 填充,并用那個(gè)數(shù)據(jù)源實(shí)例化一個(gè) ListView 組件和一個(gè)renderRow 回調(diào),它會(huì)從數(shù)組數(shù)據(jù)中帶走一個(gè) blob 并返回一個(gè)可渲染的組件。

最小的例子:

getInitialState: function() {
  var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});  return {    dataSource: ds.cloneWithRows(['row 1', 'row 2']),
  };
},render: function() {
  return (
    <ListView
      dataSource={this.state.dataSource}
      renderRow={(rowData) => <Text>{rowData}</Text>}
    />
  );
},

列表視圖還支持更高級(jí)的功能,包括帶有 sticky 頁(yè)眉的部分,頁(yè)眉和頁(yè)腳的支持,回調(diào)到可用數(shù)據(jù)的最后(onEndReached)和設(shè)備窗口變化中可見(jiàn)的行集(onChangeVisibleRows),以及一些性能優(yōu)化。

當(dāng)動(dòng)態(tài)加載一些可能非常大(或概念上無(wú)限大的)數(shù)據(jù)集時(shí),為了讓列表視圖滾送的順暢,有一些性能操作設(shè)計(jì):

  • 只有重新呈現(xiàn)改變行——提供給數(shù)據(jù)源的 hasRowChanged 函數(shù)告訴列表視圖是否需要重新呈現(xiàn)一行,因?yàn)樵磾?shù)據(jù)發(fā)生了變化——更多細(xì)節(jié)請(qǐng)看 ListViewDataSource。

  • 行限速呈現(xiàn)——默認(rèn)情況下,每次事件循環(huán)時(shí),只顯示一行 (可用pageSize道具定制)。這將工作分解為小塊,在呈現(xiàn)行時(shí),減少框架下降的機(jī)會(huì)。

Props

Edit on GitHub

ScrollView props...

dataSource 列表視圖數(shù)據(jù)源

initialListSize 數(shù)字型

多少行呈現(xiàn)在初始組件裝置中。使用這個(gè)來(lái)實(shí)現(xiàn),這樣第一個(gè)屏幕需要的數(shù)據(jù)就會(huì)一次出現(xiàn),而不是在多個(gè)框架的過(guò)程中出現(xiàn)。

onChangeVisibleRows 函數(shù)型

(visibleRows, changedRows) => void

當(dāng)可見(jiàn)的行集改變時(shí)調(diào)用。visibleRows 為所有可見(jiàn)的行映射 { sectionID: { rowID: true }} ,changedRows 為已經(jīng)改變了它們可見(jiàn)性的行映射 { sectionID: { rowID: true | false }},true 表明行可見(jiàn),而 false 表明行已經(jīng)從視圖中被刪除了。

onEndReached 函數(shù)型

當(dāng)所有行已經(jīng)呈現(xiàn)并且列表被滾動(dòng)到了 onEndReachedThreshold 的底部時(shí)被調(diào)用。提供了 native 滾動(dòng)事件。

onEndReachedThreshold 數(shù)字型

onEndReached 像素的閾值。

pageSize 數(shù)字型

每次事件循環(huán)顯示的行的數(shù)量。

removeClippedSubviews 布爾型

為提高大型列表滾動(dòng)性能的實(shí)驗(yàn)性能優(yōu)化,與溢出一起使用:“隱藏”在行容器中。使用時(shí)自己承擔(dān)風(fēng)險(xiǎn)。

renderFooter 函數(shù)型

() => renderable

頁(yè)眉和頁(yè)腳在每個(gè)呈現(xiàn)過(guò)程中都會(huì)出現(xiàn)(如果提供了這些道具)。如果重新呈現(xiàn)它們耗費(fèi)很大,那就把它們包在 StaticContainer 或其他適當(dāng)?shù)臋C(jī)制中。在每一個(gè)呈現(xiàn)過(guò)程中,頁(yè)腳始終是在列表的底部,頁(yè)眉始終在列表的頂部。

renderHeader 函數(shù)型

renderRow 函數(shù)型

(rowData, sectionID, rowID) => renderable 需要從數(shù)據(jù)源和它的 id 取走一個(gè)數(shù)據(jù)條目,并返回一個(gè)可渲染的作為行呈現(xiàn)的組件。默認(rèn)的情況下,數(shù)據(jù)正是被放入了數(shù)據(jù)源的東西,但也可以提供自定義的提取器。

renderSectionHeader 函數(shù)型

(sectionData, sectionID) => renderable

如果提供了該函數(shù),那么本節(jié)的 sticky 頁(yè)眉就會(huì)呈現(xiàn)。Sticky 行為意味著它將帶著本節(jié)頂部的內(nèi)容滾動(dòng),直到它到達(dá)屏幕的頂端,此時(shí)它會(huì)停在屏幕頂部,直到被下一節(jié)的頁(yè)眉推掉。

scrollRenderAheadDistance 數(shù)字型

在它們以像素的形式出現(xiàn)在屏幕上之前,要多早就開(kāi)始呈現(xiàn)行。

例子

Edit on GitHub

'use strict';var React = require('react-native');var {
  Image,
  ListView,
  TouchableHighlight,
  StyleSheet,
  Text,
  View,
} = React;var UIExplorerPage = require('./UIExplorerPage');var ListViewSimpleExample = React.createClass({
  statics: {
    title: '<ListView> - Simple',
    description: 'Performant, scrollable list of data.'
  },
  getInitialState: function() {    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});    return {
      dataSource: ds.cloneWithRows(this._genRows({})),
    };
  },
  _pressData: ({}: {[key: number]: boolean}),
  componentWillMount: function() {    this._pressData = {};
  },
  render: function() {    return (      <UIExplorerPage
        title={this.props.navigator ? null : '<ListView> - Simple'}
        noSpacer={true}
        noScroll={true}>        <ListView
          dataSource={this.state.dataSource}
          renderRow={this._renderRow}
        />
      </UIExplorerPage>
    );
  },
  _renderRow: function(rowData: string, sectionID: number, rowID: number) {    var rowHash = Math.abs(hashCode(rowData));    var imgSource = {
      uri: THUMB_URLS[rowHash % THUMB_URLS.length],
    };    return (      <TouchableHighlight onPress={() => this._pressRow(rowID)}>        <View>
          <View style={styles.row}>
            <Image style={styles.thumb} source={imgSource} />
            <Text style={styles.text}>
              {rowData + ' - ' + LOREM_IPSUM.substr(0, rowHash % 301 + 10)}            </Text>
          </View>
          <View style={styles.separator} />
        </View>
      </TouchableHighlight>
    );
  },
  _genRows: function(pressData: {[key: number]: boolean}): Array<string> {    var dataBlob = [];    for (var ii = 0; ii < 100; ii++) {      var pressedText = pressData[ii] ? ' (pressed)' : '';
      dataBlob.push('Row ' + ii + pressedText);
    }    return dataBlob;
  },
  _pressRow: function(rowID: number) {    this._pressData[rowID] = !this._pressData[rowID];    this.setState({dataSource: this.state.dataSource.cloneWithRows(      this._genRows(this._pressData)
    )});
  },
});var THUMB_URLS = ['https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851549_767334479959628_274486868_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851561_767334496626293_1958532586_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851579_767334503292959_179092627_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851589_767334513292958_1747022277_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851563_767334559959620_1193692107_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851593_767334566626286_1953955109_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851591_767334523292957_797560749_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851567_767334529959623_843148472_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851548_767334489959627_794462220_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851575_767334539959622_441598241_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-ash3/t39.1997/p128x128/851573_767334549959621_534583464_n.png', 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851583_767334573292952_1519550680_n.png'];var LOREM_IPSUM = 'Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix civibus corrumpit referrentur. Te nam case ludus inciderint, te mea facilisi adipiscing. Sea id integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei. Eu paulo sapientem vulputate est, vel an accusam intellegam interesset. Nam eu stet pericula reprimique, ea vim illud modus, putant invidunt reprehendunt ne qui.';/* eslint no-bitwise: 0 */var hashCode = function(str) {  var hash = 15;  for (var ii = str.length - 1; ii >= 0; ii--) {
    hash = ((hash << 5) - hash) + str.charCodeAt(ii);
  }  return hash;
};var styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    justifyContent: 'center',
    padding: 10,
    backgroundColor: '#F6F6F6',
  },
  separator: {
    height: 1,
    backgroundColor: '#CCCCCC',
  },
  thumb: {
    width: 64,
    height: 64,
  },
  text: {
    flex: 1,
  },
});module.exports = ListViewSimpleExample;


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)