react-native-nlist

react-nativ 的 ListView 从rn 这个跨平台框架诞生 到目前为止 一直 被 开发者 诟病,卡顿 视图不回收 内存爆炸 滑动不流畅 等问题 虽然官方有出 FlatList 带有视图重用的
组件但是 性能表现 一滚动 内存疯狂涨 cpu 占用 超过 100% 而且 列表过长 快速滑动 会有 渲染空白的 问题 (由于RN的渲染通知机制 快速滑动 需要大量计算 触发渲染 cpu占用过高 而且js单线程 再加上 需要和原生交互 等等 性能消耗问题 导致 ) 听说fb有要重构rn的消息 但是不知道 这次 框架核心设计 是否和原来的 有质的提升

ListView 性能解决方案 原生代码实现 滑动流畅不卡顿 内存回收 视图重用 上拉刷新 下拉加载 支持本地 自定义刷新动画 支持itemView动态 高度

性能表现 优于 目前所有 列表组件。

** android demo apk 文件 下载 **

github地址 react-native-nlist

IOS实现

使用 UITabView
基于 react-native-tableview 做了优化内存 api封装 添加MJRefresh 封装刷新 加载事件 等

Android 实现

Android 使用 Recyclerview 实现 自己编写的一套 视图模板重用逻辑 加上 滚动事件 下拉刷新 下拉刷新 SmartRefresh 等封装

性能测试

ios 使用 iphone 6s 10015 条数据的列表,大量的图片. 而且图片没有使用 SDWebImage 缓存库和内存缓存优化

我疯狂的滑动列表到 4679条数据 这个时候 内存的使用量 是 111m 附图中也可以看到 cpu 使用情况 整个过程最高没有超过 34% cpu占用率
1png

Android 使用 小米6 同意 10015 条数据的超长列表, 和大量图片资源. 而且图片没有使用 Glide 缓存库和内存缓存优化

我疯狂的滑动列表到 2569条数据 Android 的列表滚动有最大阈值限制不像苹果是一个加速过程 越滑滚动越越快 当我滑到2千多条数据的时候已经用了2分钟的样子 手痛划不动了 ~~(╯﹏╰) 这是 内存使用情况 123 MB
3png

安装

$ npm install react-native-nlist --save

配置

iOS

  1. 打开xocde, 在你的项目文件目录上, 鼠标右键 添加文件到项目 your project nameAdd Files to
  2. 选择目录 node_modulesreact-native-nlist 选中 /node_modules/react-native-nlist/ios/RNNlistcode目录添加到项目中
  3. 添加 MJRefresh 库依赖 使用 cocoapods(如果不知道ios的包依赖请自行百度或google这个关键字) 创建 podfile 文件在你的ios项目根目下 /ios/Podfile 内容如下仅参考
 # Uncomment the next line to define a global platform for your project
platform :ios, '8.0'
target 'demo' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!
  # Pods for Driver
  use_frameworks!
  pod 'MJRefresh'
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '4.0'
    end
  end
end

pod 'MJRefresh' 这一句是依赖声明
然后在ios项目根目录下执行安装命令 pod install
4. 安装完成之后 通过 生成出来 .xcworkspace 文件打开你的ios项目 (Cmd+R)< 编译运行

android

自动安装
react-native link 执行命令完事emmmm

手动安装

  1. 打开你的 android/app/src/main/java/[...]/MainApplication.java 文件
  • 导入类 import com.janiokq.Nlist.RNNlistPackage; 在 MainApplication.java文件中
  • 实例化 new RNNlistPackage() 添加在 getPackages() 方法中
  1. 添加settings.gradle依赖配置项目目录 android/settings.gradle:
    include ':react-native-nlist'
    project(':react-native-nlist').projectDir = new File(rootProject.projectDir, 	'../node_modules/react-native-nlist/android')
    
  2. 添加 依赖声明 android/app/build.gradle:
      compile project(':react-native-nlist')
    

属性说明

onScroll

 {

  x:x,

  y:y,

  nx:nx,

  ny:ny,

  }
ny,nx  android 是 最近一次的滚动 差值       正数为向下滚动     负数为向上滚动

reactModuleForCell

ios  渲染模板名称     通过 AppRegistry.registerComponent   生成
  
AppRegistry.registerComponent('Itemlist', () => Itemlist);

renderItem

android  渲染模板名称      一个类的名称   

springback

android 特有 模仿ios的滑动回弹效果 在头部或者尾部的时候 布尔值 true 或者false

canRefresh

是否支持下拉刷新 布尔值 true 或者false

canLoadmore

是否支持加载更多 布尔值 true 或者false

refreshState

下拉刷新 状态 控制

loadinState

加载刷新 状态 控制

onRefresh

刷新事件

onLoadmore

加载事件

dataSource

数据源 Array 一个数据 item中必须是对象 对象必须包含height 属性声明 item的高度 然后在对象中可以添加自己想要的属性会传递到渲染模板中

reference

获取 视图引用

method

scrollToPosition 滚动到指定item

scrollToPosition(index: number);

使用

详细使用请参考 demo

list 使用

import RNNlist from 'react-native-nlist';

// TODO: What to do with the module?
RNNlist;

 <RNNlist
 
		 reference={(r)=>{
			this.RNNlist = r;
		}}
		
        onScroll={(e)=>{
			 // {
			 // x:x,
			 // y:y,
			 // nx:nx,
			 // ny:ny,
			 // }
			 // android only
			//nx,ny android is The last rolling start difference The negative number is upward. The positive number is downward.


        }}
        
        inserttheway={0}
        //ios   Rendering template
        reactModuleForCell="Itemlist"
        //android  Rendering template
        renderItem={Itemlist}
        //Rendering initialization of Android
        Initializeprops={{}}

        //Android rolling rebound effect
        springback={true}
        //Android template quantity
        rowHeight={40}
        style={{
          width:width,
          height:height
        }}

        canRefresh={true}
        canLoadmore={true}

        refreshState={this.state.refreshState}
        loadinState={this.state.loadinState}
        dataSource={this.state.dataSource}

        onRefresh={()=>{
          setTimeout(()=>{
            this.getdata();
          },1000)
        }}
        onLoadmore={()=>{
          setTimeout(()=>{
            this.adddata();
          },1000)
        }}
    />
    

模板注册声明


class Itemlist extends  Component{
  constructor(props){
    super(props)
  }
  render() {
    let data  =  this.props;
    if(Platform.OS=='ios'){
        data =this.props.data;
    }

    return (
      <View style={{flex:1,}} >
            <View style={{
                width:width,
                height:data.height,
              }} >

              <Text>{data.index}</Text>

              <Image 
              // source={{
              //   uri:'http://img3.imgtn.bdimg.com/it/u=3360690558,3623061169&fm=11&gp=0.jpg'
              // }}
              source={{uri: 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3360690558,3623061169&fm=111&gp=0.jpg'}}
              style={{
                width:width,
                height:data.height-30,
              }}
              resizeMode='stretch'
              />

              </View>
      </View>
    )
  }
}

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