CRNListView

一个核心组件,用于高效地显示一个可以垂直滚动的变化的数据列表。最基本的使用方式就是创建一个CRNListView.DataSource数据源,然后给它传递一个普通的数据数组,再使用数据源来实例化一个ListView组件,并且定义它的renderRow回调函数,这个函数会接受数组中的每个数据作为参数,返回一个可渲染的组件(作为listview的每一行)。

该ListView是在Native的UITableView基础上封装的列表视图组件,与Facebook官方的ListView相比,支持cell的重用,优化了性能,并且集成了下拉刷新、点击加载更多、右侧索引栏等功能,但使用该ListView必须事先知道每个要渲染的row或sectionHeader的高度。

最简单的例子:

constructor(props) {
  super(props);
  var ds = new CRNListView.DataSource({});
  this.state = {
    dataSource: ds.cloneWithRows(['row 1', 'row 2']),
  };
}
render() {
  return (

<
CRNListView
      dataSource={this.state.dataSource}
      renderRow={(rowData) =
>
<
Text
>
{rowData}
<
/Text
>
}
    /
>

  );
}

属性

dataSource CRNListViewDataSource

CRNListView.DataSource实例(列表依赖的数据源)

renderHeader function

() => renderable

渲染整个ListView的头部,页头会在每次渲染过程中都重新渲染(如果提供了这些属性)。如果它们重绘的性能开销很大,把他们包装到一个StaticContainer或者其它恰当的结构中。

renderRow function

(rowData, sectionID, rowID) => renderable

从数据源(Data source)中接受一条数据,以及它和它所在section的ID。返回一个可渲染的组件来为这行数据进行渲染。默认情况下参数中的数据就是放进数据源中的数据本身,不过也可以提供一些转换器。

rowHeight number

如果每个row都是相同的高度,可以在此统一设置,设置了rowHeight后,对rowHeights的设置无效

rowHeights array or json

如果各个row的高度不同,需在此设置,数据结构和dataSource的数据结构一致:

 sectionID_1: { rowID_1: height1, ... }, ... }

或者:

{ sectionID_1: [ height1, height2, ... ], ... }

或者:

[ [ height1, height2, ... ], ... ]

renderSectionHeader function

(sectionData, sectionID) => renderable

如果提供了此函数,会为每个小节(section)渲染一个粘性的标题。

粘性是指当它刚出现时,会处在对应小节的内容顶部;继续下滑当它到达屏幕顶端的时候,它会停留在屏幕顶端,一直到对应的位置被下一个小节的标题占据为止。

sectionHeaderHeight number

如果每个sectionHeader都是相同的高度,可以在此统一设置,设置了sectionHeader后,对sectionHeaders的设置无效

sectionHeaderHeights array or json

如果各个sectionHeader的高度不同,需在此设置,数据结构和dataSource的sectionData的数据结构一致:

{ sectionID_1: height1, sectionID_2: height2, ... }

或者:

[ height1, height2, ... ]

onSelect function

(rowData,sectionID,rowID) => void

用户点击某个row的时候触发的回调,传递进来的参数是点击的rowData和对应的sectionID,rowID

enablePullDownToRefresh boolean

是否开启下拉刷新,默认否

onPullDownToRefresh function

触发下拉刷新后的回调,刷新数据完成后需要设置isFinishRefresh为true

enableLoadMore boolean

是否开启点击加载更多,默认否

onLoadMore function

点击加载更多后的回调,刷新数据完成后需要设置loadMoreState的状态

loadMoreState enum('normal', 'loading', 'done')

点击加载更多的状态,接收到onLoadMore的回调是设置为loading,加载数据完成后如果还有数据可加载则设置为normal,如果没有数据可加载了则设置为done

sectionIndexTitles array

ListView右侧的索引数组的标题。(暂时只有ios支持)

mappingForSectionIndexTitles object

ListView右侧的索引数组标题与索引section的对应关系,默认是sectionIndexTitles的每个title对应该title的下标。(暂时只有ios支持)

方法

finishRefresh()

下拉刷新数据完成后需要调用此方法

scrollTo(x: number, y: number, animated: boolean)

滚动到指定的x, y偏移处。第三个参数为是否启用平滑滚动动画。

使用示例:

scrollTo({x: 0, y: 200, animated: true})

例子

'use strict';

import {
    AppRegistry,
    View,
    Dimensions,
    TouchableOpacity,
    Text,
    Image,
}   from 'react-native';

import React, {Component} from 'react';


import { CRNListView } from "@ctrip/crn";

let ds = new CRNListView.DataSource({})
class RNDemo extends Component {

    constructor(props){
        super(props);

        var data=[];
        for (var i = 0; i 
<
 3; i++) {
            var items = [];
            for (var j = 0; j 
<
 20; ++j) {
                items.push('item--origin--'+j);
            }
            data.push(items)
        }
        var dataSource= ds.cloneWithRowsAndSections(data)
        this.state={
            dataSource:dataSource,
            isFinishRefresh:false,
            loadMoreState:'normal',
        }
    }

    render(){

        var rowHeights=[];
        for (var i = 0; i 
<
 3; i++) {
            var items = [];
            for (var j = 0; j 
<
 20; ++j) {
                items.push(j*20);
            }
            rowHeights.push(items)
        }

        var sectionHeaderHeights = [];
        for (var j = 0; j 
<
 3; ++j) {
            sectionHeaderHeights.push(j*20);
        }
        return (

<
CRNListView style={{flex:1}}
                      ref={listView =
>
 this.listView = listView}
                      rowHeight={50}
                      renderRow={this.renderRow}
                      sectionHeaderHeight={60}
                      renderSectionHeader={this.renderSectionHeader}
                      renderHeader={this.renderHeader}
                      onPress={this.onPress.bind(this)}
                      enablePullDownToRefresh={true}
                      onPullDownToRefresh={this.onPullDownToRefresh.bind(this)}
                      enableLoadMore={true}
                      onLoadMore={this.onLoadMore.bind(this)}
                      dataSource={this.state.dataSource}
                      loadMoreState={this.state.loadMoreState}
                      rowHeights={rowHeights}
                      sectionHeaderHeights={sectionHeaderHeights}

>
<
/CRNListView
>

        );

    }

    renderRow(rowData, sectionID, rowID) {
        return (

<
View
>
<
Image style={{width:30,height:30}} source={{uri: 'https://ss3.bdstatic.com/iPoZeXSm1A5BphGlnYG/icon/95487.png'}}/
>
<
Text
>
section:{sectionID},row:{rowID},data:{rowData}
<
/Text
>
<
/View
>
);
    }

    renderSectionHeader(sectionData, sectionID){
        return (

<
View style={{backgroundColor:"#cccccc",flex:1}}
>
<
Text style={{marginTop:20}}
>
'*********section:{sectionID}*********'
<
/Text
>
<
/View
>
);
    }

    renderHeader(){
        return (

<
View style={{backgroundColor:"#097f34",flex:1}}
>
<
Text style={{marginTop:20}}
>
'++++++++++tableHeader++++++++++'
<
/Text
>
<
/View
>
);
    }

    onPress(rowData,sectionID,rowID){
        alert(JSON.stringify(rowData)+'---'+JSON.stringify(sectionID)+'---'+JSON.stringify(rowID))
    }

    onPullDownToRefresh(){
        var self=this
        setTimeout(function(){
            var data=[];
            for (var i = 0; i 
<
 3; i++) {
                var items = [];
                for (var j = 0; j 
<
 20; ++j) {
                    items.push('item--refresh--'+j);
                }
                data.push(items)
            }
            var dataSource = ds.cloneWithRowsAndSections(data);
            self.setState({dataSource:dataSource})
            self.listView.finishRefresh();
        },2000)

    }

    onLoadMore(){
        var self=this
        self.setState({loadMoreState:'loading'})
        setTimeout(function(){
            var data=[];
            for (var i = 0; i 
<
 3; i++) {
                var items = [];
                for (var j = 0; j 
<
 20; ++j) {
                    items.push('item--loadmore--'+j);
                }
                data.push(items)
            }
            var dataSource= ds.cloneWithRowsAndSections(data);
            self.setState({dataSource:dataSource, loadMoreState:'normal'})
        },2000)
    }

}


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

截图

results matching ""

    No results matching ""