美文网首页
react native recyclerlistview使用

react native recyclerlistview使用

作者: MasterPaul | 来源:发表于2019-12-29 20:46 被阅读0次

https://github.com/Flipkart/recyclerlistview

概述和功能

RecyclerListView 是一个高性能的列表(listview)组件,同时支持 React Native 和 Web ,并且可用于复杂的列表。RecyclerListView 组件的实现灵感,来自于 Android RecyclerView原生组件及iOS UICollectionView原生组件。

优点

解决了FlatList快速滚动出现白屏,列表数据很大的时候安卓滚动卡顿的问题

缺点

需要提前计算并设置layout。

原理

RecyclerListView使用“cell recycling”来重用不再可见的视图来呈现项目,而不是创建新的视图对象。 对象的创建非常昂贵并且带有内存开销,这意味着当您滚动列表时内存占用量不断增加。 从内存中释放不可见的项目是另一种技术,但这会导致创建更多的对象和大量的垃圾收集。 回收是渲染无限列表的最佳方式,不会影响性能或内存效率。

为什么需要RecyclerListView

我们知道,React Native 的其他列表组件如ListView,会一次性创建所有的列表单元格——cell。如果列表数据比较多,则会创建很多的视图对象,而视图对象是非常消耗内存的。所以,ListView组件,对于我们业务中的这种无限列表,基本上是不可以用的。

对于React Native 官方提供的高性能的列表组件FlatList, 在Android设备上的表现,并不是十分友好。它的实现原理,是将列表中不在可视区域内的视图,进行回收,然后根据页面的滚动,不断的渲染出现在可视区域内的视图。这里需要注意的是,FlatList是将不可见的视图回收,从内存中清除了,下次需要的时候,再重新创建。这就要求设备在滚动的时候,能快速的创建出需要的视图,才能让列表流畅的展现在用户面前。而问题也就出现在这里,Android设备因为老化等原因,计算力等跟不上,加之React Native 本身 JS 层与 Native 层之间交互的一些问题(这里不做深入追究),导致创建视图的速度达不到使列表流畅滚动的要求。当数据很大的时候就会出现滑动卡顿的现象。

1、先安装 yarn add recyclerlistview


const ViewTypes = {
    HEADER : 0,
    CELL : 1
}

const HEADER_HEIGHT1 = screen.scaleSize( 1850)
const HEADER_HEIGHT2 =  screen.scaleSize(2510)
const CELL_HEIGHT = screen.scaleSize( 420 )

let pageNo = 1;//当前第几页
let totalPage = 50;//总的页数

class Home extends Component<Props> {

    constructor(props) {
        super(props);
  
        this._renderRow = this._renderRow.bind(this)
        this.getLayoutProvider = this.getLayoutProvider.bind(this)

    }

    getLayoutProvider(showRemind){
        let layoutProvider = new LayoutProvider((i)=>{
            if(i == 0){
                return ViewTypes.HEADER
            }
            return ViewTypes.CELL
        },(type,dim)=>{
            dim.width = screen.width
            switch (type) {
                case ViewTypes.HEADER:
                    dim.height = showRemind ?  HEADER_HEIGHT2 : HEADER_HEIGHT1
                    break;
                case ViewTypes.CELL:
                    dim.height = CELL_HEIGHT
                    break;

            }
        })
        return layoutProvider
    }

    state = {
        loading:false,
        data:[0],

        tehuiData:[],
        monthData:[],
        remindList:[],
        showFoot:2,// 控制foot, 0:隐藏footer  1:已加载完成,没有更多数据   2:显示加载中
        layoutProvider:this.getLayoutProvider(false)

    }



    _renderRow(type,data){

        switch (type) {

            case ViewTypes.HEADER:

                return this._renderHeaderView()

            case  ViewTypes.CELL:

                return (
                    <HouseCell
                        item={data}
                        onPress={(item)=>{
                                  this.props.navigation.navigate('Detail',{houseId:item.id,datafrom:item.datafrom})
                              }}
                    />
                )

            default:
                return null;
        }
    }


    _keyExtractor = (item,index) => `index_${index}`;

    //为空时
    listEmptyComponent() {
        return (
            <View style={{ width: screen.width, height: screen.height - 140,
                justifyContent: 'center', alignItems: 'center',}}>
                <Text style={{marginTop: 15, fontSize: 18, color: '#999999',}}>没有数据</Text>
            </View>
        );
    }

    render() {


        let content = (
            <LoadingView />
        )
        if(this.state.data.length > 0 && this.state.monthData.length > 0 && this.state.tehuiData.length > 0
        ){
            let dataProvider = new DataProvider((r1,r2)=>{
                return r1 !== r2
            }).cloneWithRows(this.state.data)

            return (
<RecyclerListView

                        dataProvider={dataProvider}
                        rowRenderer={this._renderRow}
                        layoutProvider={this.state.layoutProvider}
                        renderFooter={()=>(
                            <ListFooterView showFoot={this.state.showFoot}/>
                        )}
                        onEndReached={this._onEndReached.bind(this)}
                        onEndReachedThreshold={0.1}
                        scrollViewProps={{
                            refreshControl: (
                                <RefreshControl
                                    refreshing={this.state.loading}
                                    onRefresh={ this.getInitData}
                                />
                            )
                        }}

                    />)
        }



    }

    _onEndReached(){
        if(this.pageNo === 1){
            return;
        }
        console.log('滑到底部了')
        //如果是正在加载中或没有更多数据了,则返回
        if(this.state.showFoot !== 0 ){
            return ;
        }
        //如果当前页大于或等于总页数,那就是到最后一页了,返回
        if((pageNo!=1) && (pageNo>=totalPage)){
            return;
        } else {
            pageNo++;
        }
        //底部显示正在加载更多数据
        this.setState({showFoot:2});
        //获取数据
        this.fetchData( );
    }
}


相关文章

网友评论

      本文标题:react native recyclerlistview使用

      本文链接:https://www.haomeiwen.com/subject/sxduoctx.html