学习iOS开发的同学应该都知道UITableView,几乎每个APP中都有它的存在,而且衍生出各种形态;那么同样,ListView就是在React Native中的tableView,而且更加简单和灵活易用;让我们一起搞定它。

一、前言

ListView组件是React Native中一个比较核心的组件,用途非常的广; 该组件设计用来高效的展示垂直滚动的数据列表:

  1.1   首先创建一个ListView.DataSource数据源,然后给它传递一个普通的数据数组;

  1.2  使用数据源(data source)实例化一个ListView组件,定义一个renderRow回调函数,这个函数会接受数组中的每个数据作为参数,并返回一个可渲染的组件(该就是列表的每一行的item)。

二、ListView常用的属性

ScrollView 相关属性样式全部继承

dataSource   ListViewDataSource  设置ListView的数据源

initialListSize  number

设置ListView组件刚刚加载的时候渲染的列表行数,用这个属性确定首屏或者首页加载的数量,而不是花大量的时间渲染加载很多页面数据,提高性能。

onChangeVisibleRows  function

(visibleRows,changedRows)=>void。

当可见的行发生变化的时候回调该方法。

onEndReachedThreshold  number

当偏移量达到设置的临界值调用onEndReached

onEndReached function

当所有的数据项行被渲染之后,并且列表往下进行滚动。一直滚动到距离底部onEndReachedThredshold设置的值进行回调该方法。原生的滚动事件进行传递(通过参数的形式)。

pageSize   number 每一次事件的循环渲染的行数

removeClippedSubviews  bool

该属性用于提供大数据列表的滚动性能。该使用的时候需要给每一行(row)的布局添加over:'hidden'样式。该属性默认是开启状态。

renderFooter function 方法  ()=>renderable

在每次渲染过程中头和尾总会重新进行渲染。如果发现该重新绘制的性能开销比较大的时候,可以使用StaticContainer容器或者其他合适的组件。

renderHeader  function 方法

在每一次渲染过程中Footer(尾)该会一直在列表的底部,header(头)该会一直在列表的头部,用法同上。

renderRow function  (rowData,sectionID,rowID,highlightRow)=>renderable

该方法有四个参数,其中分别为数据源中一条数据,分组的ID,行的ID,以及标记是否是高亮选中的状态信息。

renderScrollComponent function

方法 (props)=>renderable  该方法可以返回一个可以滚动的组件。默认该会返回一个ScrollView

renderSectionHeader function (sectionData,sectionID)=>renderable

如果设置了该方法,这样会为每一个section渲染一个粘性的header视图。该视图粘性的效果是当刚刚被渲染开始的时候,该会处于对应的内容的顶部,然后开始滑动的时候,该会跑到屏幕的顶端。直到滑动到下一个section的header(头)视图,然后被替代为止。

renderSeparator function

(sectionID,rowID,adjacentRowHighlighted)=>renderable

如果设置该方法,会在被每一行的下面渲染一个组件作为分隔。除了每一个section分组的头部视图前面的最后一行。

scrollRenderAheadDistance number

  进行设置当该行进入屏幕多少像素以内之后就开始渲染该行

三、ListView的高阶特性

ListView同样支持一些高级特性,包括设置每一组的粘性的头部(类似于iPhone)、支持设置列表的header以及footer视图、当数据列表滑动到最底部的时候支持onEndReached方法回调、设备屏幕列表可见的视图数据发生变化的时候回调onChangeVisibleRows以及一些性能方面的优化特性。

ListView设计的时候,当需要动态加载非常大的数据的时候,下面有一些方法性能优化的方法可以让我们的ListView滚动的时候更加平滑:

(1)只更新渲染数据变化的那一行  ,rowHasChanged方法会告诉ListView组件是否需要重新渲染当前那一行。

(2)选择渲染的频率,默认情况下面每一个event-loop(事件循环)只会渲染一行(可以同pageSize自定义属性设置)。这样可以把大的工作量进行分隔,提供整体渲染的性能。

四、综合大演练

4.1  ListView练习,代码如下:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, { Component } from 'react';
import {AppRegistry,StyleSheet,Text,View,ListView,Image,TouchableOpacity
} from 'react-native';
var Wine = require('./Wine.json');
var Dimensions = require('Dimensions');
var {width} = Dimensions.get('window');
export default class FListViewDemo1 extends Component{constructor(props){super(props);var ds = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2});this.state = {dataSource:ds.cloneWithRows(Wine)};}render(){return(<ListViewstyle = {{backgroundColor:'white'}}dataSource = {this.state.dataSource}renderRow = {this.renderRow}/>
    );}renderRow(rowData,sectionID,rowID,highlightRow){return(<TouchableOpacity activeOpacity={0.4}><View style={styles.cellViewStyle}><Image source={{uri:rowData.image}} style={styles.leftImageStyle}/><View style = {styles.rightViewStyle}><Text style={styles.topTitleStyle}>{rowData.name}</Text><Text style={styles.bottomTitleStyle}>¥{rowData.money}</Text></View></View></TouchableOpacity>
);}
}const styles = StyleSheet.create({cellViewStyle:{padding:10,backgroundColor:'white',borderBottomWidth:0.3,borderBottomColor:'#e8e8e8',flexDirection:'row'},leftImageStyle:{width:60,height:60,marginRight:10,justifyContent:'center'},topTitleStyle:{color:'red',fontSize:15,width:width * 0.8,marginBottom:10},bottomTitleStyle:{},rightViewStyle:{}
});

4.2  带有组头的汽车品牌展示

核心代码:

完整代码:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, { Component } from 'react';
import {AppRegistry,StyleSheet,Text,View,ListView,Image,TouchableOpacity
} from 'react-native';var Car = require('./Car.json');export default class FListViewDemo1 extends Component{constructor(props){super(props);var getSectionData = (dataBlob,sectinID) =>{return dataBlob[sectinID];}var getRowData = (dataBlob,sectinID,rowID) =>{return dataBlob[sectinID + ':' + rowID];}this.state = {dataSource:new ListView.DataSource({getSectionData:getSectionData,//获取组中数据getRowData:getRowData,//获取行中数据rowHasChanged:(r1,r2) => r1 !== r2,sectionHeaderHasChanged:(s1,s2) => s1 !== s2})};}render(){return(<View style = {styles.outerViewStyle}><View style={styles.headerViewStyle}><Text>SeeMyGo品牌</Text></View><ListViewdataSource={this.state.dataSource}renderRow={this.renderRow}renderSectionHeader={this.renderSectionHeader}style ={{backgroundColor:'white'}}/></View>
);}renderRow(rowData){return(<TouchableOpacity actionOpacity ={0.5}><View style={styles.rowStyle}><Image source={{uri:rowData.icon}} style={styles.rowImageStyle}/><Text>{rowData.name}</Text></View></TouchableOpacity>
    );}renderSectionHeader(sectinData,sectionID){return(<View style={styles.sectionHeaderViewStyle}><Text>{sectinData}</Text></View>
    );}componentDidMount(){//调用Json数据this.loadDataFromJson();}loadDataFromJson(){//拿到json数据var jsonData = Car.data;//定义一下变量var dataBlob = {},sectionIDs = [],rowIDs = [],cars = [];//遍历for(var i = 0;i<jsonData.length;i++){//1.把组号放入sectionID数组中
      sectionIDs.push(i);//2.把组中的内容放入dataBlob中dataBlob[i] = jsonData[i].title;//3.取出该组中所有的车cars = jsonData[i].cars;//4.遍历所有的测数组rowIDs[i] = [];for(var j = 0;j<cars.length;j++){//把行号放入rowIDs
        rowIDs[i].push(j);//把每一行中的内容放入dataBlob对象中dataBlob[i+':'+j] = cars[j];}}//更新状态this.setState({dataSource:this.state.dataSource.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs)});}
}const styles = StyleSheet.create({outerViewStyle:{flex:1},headerViewStyle:{height:64,backgroundColor:'orange',justifyContent:'center',alignItems:'center'},rowStyle:{flexDirection:'row',alignItems:'center',padding:10,borderBottomColor:'#e8e8e8',borderBottomWidth:0.3},rowImageStyle:{width:70,height:70},sectionHeaderViewStyle:{backgroundColor:'#e8e8e8',height:25,justifyContent:'center'}
});

View Code

运行结果:

项目技术点分析:

在React Native中,ScrollView组件可以使用 stickyHeaderIndices 轻松实现 sticky 效果;而使用ListView组件时,使用 stickyHeaderIndices 则不生效。

如何实现滚动时每个section header会吸顶?

在ListView中要实现 sticky ,需要使用 cloneWithRowsAndSections 方法,将 dataBlob(object), sectionIDs (array), rowIDs (array) 三个值传进去。

dataBlob

 dataBlob 包含ListView所需的所有数据(section header 和 rows),在ListView渲染数据时,使用getSectionData 和 getRowData 来渲染每一行数据。 dataBlob 的 key 值包含 sectionID rowId

 sectionIDs

 sectionIDs 用于标识每组section。

rowIDs

rowIDs 用于描述每个 section 里的每行数据的位置及是否需要渲染。在ListView渲染时,会先遍历 rowIDs 获取到对应的 dataBlob 数据。

  模拟对应的数据结构

  在 DataSource 中,设置ListView获取row和section的方法

  最后

  1. 刷新状态,将数据传入到listView中:

this.setState({dataSource:this.state.dataSource.cloneWithRowsAndSections(dataBlob,sectionIDs, rowIDs)
});

  2. 设置listView的相关属性:

<ListViewdataSource = {this.state.dataSource}renderRow = {this.renderRow}renderSectionHeader = {this.renderSectionHeader}/>

4.3  用ListView实现九宫格布局

相关技术点:

通常情况下,我们对ListView的操作是纵向的,如果是横向的,则需要设置ListView的contentContainerStyle属性,添加flexDirection:‘row’让多个ListView在同一行显示,而且通过flexWrap:'wrap'进行换行。

核心代码:

完整代码:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, { Component } from 'react';
import {AppRegistry,StyleSheet,Text,View,ListView,Image,TouchableOpacity, // 不透明度触摸
  AlertIOS
} from 'react-native';var Dimensions = require('Dimensions');
var screenWidth = Dimensions.get('window').width;// 导入json数据
var shareData = require('./shareData.json');// 一些常量设置
var cols = 3;
var cellWH = 100;
var vMargin = (screenWidth - cellWH * cols) / (cols + 1);
var hMargin = 25;// ES5
var AListViewDemo = React.createClass({// 设置默认值,固定值()
  getDefaultProps(){return{}},// 设置一些初始值(可以变化)
   getInitialState(){// 创建数据源var ds = new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2});return{dataSource: ds.cloneWithRows(shareData.data)}},render(){return(<ListViewdataSource={this.state.dataSource}renderRow={this.renderRow}contentContainerStyle={styles.listViewStyle}/>
      );},// 单独的cell
  renderRow(rowData){return(<TouchableOpacity activeOpacity={0.5} onPress={()=>{AlertIOS.alert('哈哈')}}><View style={styles.innerViewStyle}><Image source={{uri: rowData.icon}} style={styles.iconStyle}/><Text>{rowData.title}</Text></View></TouchableOpacity>
     );}});const styles = StyleSheet.create({listViewStyle:{// 改变主轴的方向flexDirection:'row',// 多行显示flexWrap:'wrap'},iconStyle:{width:80,height:80},innerViewStyle:{width:cellWH,height:cellWH,marginLeft:vMargin,marginTop:hMargin,// 居中alignItems:'center'}
});AppRegistry.registerComponent('AListViewDemo', () => AListViewDemo);

View Code

运行效果:

4.4  自定义Cell

相关技术点:

在实际开发中,ListView会有多种样式,那么这里面就需要我们自己自定义cell来完成各种界面布局需求。

核心代码:  

4.5  ListView中多界面传参

相关技术点:

1. 关联界面数据顺传和逆传;

2. 采用通知实现非关联界面数据传递;

3. 购物车逻辑处理;

4. 处理RN中对象深浅拷贝。

核心代码: 

案例截图: 

转载于:https://www.cnblogs.com/xjf125/p/10387862.html

React Native常用组件之ListView组件相关推荐

  1. React Native使用指南-原生UI组件

    在如今的App中,已经有成千上万的原生UI部件了--其中的一些是平台的一部分,另一些可能来自于一些第三方库,而且可能你自己还收藏了很多.React Native已经封装了大部分最常见的组件,譬如Scr ...

  2. React Native常用组件之ListView

    1. ListView常用属性 ScrollView 相关属性样式全部继承 dataSource ListViewDataSource 设置ListView的数据源 initialListSize n ...

  3. React Native FlatList和SectionList列表组件

    FlatList 之前使用的组件是ListView,当时要添加一个下拉刷新,上拉加载的功能,所以对ListView做了一些封装,但是后来看官方文档,不建议再使用ListView,因为效率问题,做过An ...

  4. 如何在React Native中使用文本输入组件?

    You know, an app becomes more authentic and professional when there is the interaction between the a ...

  5. 【React Native开发】React Native控件之RefreshControl组件具体解释(21)

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50672747 本文出自:[江清清的博客] (一)前言 [好消息]个人 ...

  6. native react 折线图_【详解】纯 React Native 代码自定义折线图组件(译)

    本文为 Marno 翻译,转载必须保留出处! 公众号[ Marno ],关注后回复 RN 加入交流群 React Native 优秀开源项目大全:http://www.marno.cn 一.前言 在移 ...

  7. 【React Native开发】React Native控件之TextInput组件讲解与QQ登录界面实现(11)

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50589570 本文出自:[江清清的博客] (一)前言 [好消息]个人 ...

  8. React Native常用第三方汇总

    React Native 项目常用第三方组件汇总:  react-native-animatable 动画  react-navigation  github : https://reactnavig ...

  9. React Native常用第三方组件汇总【建议收藏】

    react-native-system-setting 修改系统设置 react-native-picker-select 数据选择 react-native-searchable-dropdown ...

  10. android 高德地图 3d,在React Native中使用 高德地图组件react-native-amap3d

    react-native 高德地图组件,使用最新 3D SDK,支持 Android + iOS,受react-native-maps启发,提供功能丰富且易用的接口. node 主要功能:react ...

最新文章

  1. oracle11g insufficient,ORACLE11GORA-01031:insufficientprivileges
  2. 哪些是能安装mysql的文件_安装mysql详细步骤有哪些?
  3. fuzz系列之libfuzzer
  4. mybatis下log4j使用
  5. olap mysql_MySQL与OLAP:分析型SQL查询最佳实践探索
  6. pip is configured with locations that require TLS/SSL, however the ssl module in Python is not avail
  7. 面试官让我用channel实现sync包里的同步锁,是不是故意为难我?
  8. matlab fft freqz,【急】请教 fft、freqz、bode 求相频响应的区别及原因
  9. 利用scrapy爬取美图录网站图集按模特姓名存储到本地(三)
  10. 包过滤型防火墙iptables
  11. 忍者安全渗透系统(NINJITSU OS V3)的安装详细过程,亲测新旧vm版本都可安装,附带下载来源
  12. 商品库存盘点 门店和仓库 需要盘点的物品都可以使用 多种方式设备可以盘点商品库存 移动智能终端盘点机盘点
  13. php sapi 那些坑,安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
  14. WPA2/WPA3混合与WPA3的hostapd配置区别
  15. 一文搞懂广播电视节目制作经营许可证办理流程
  16. apdl与传统计算机语言,ANSYS经典APDL语言详解及ANSYS二次开发
  17. arduino 天下第一(暴论) -- 智能猫眼与 SDDC 连接器移植到 arduino 上
  18. MySQL数据库学习笔记(10)- distinct与in和exists子查询
  19. 《redis设计与实现》
  20. 华为RPA WeAutomate Studio使用心得

热门文章

  1. 从零实现深度学习框架——优化反向传播相关代码
  2. 每周荐书:微服务、SQL调优、机器学习(评论送书)
  3. 优化理论05----最速下降法、最速下降法思想、python实现
  4. 25 矩阵——QR分解、Householder 矩阵、镜面反射
  5. Tensorflow:模型保存和服务
  6. 6个座位办公室最佳位置_6个办公室座位的最佳位置 六个最好的办公室座位位置...
  7. 小蠓虫如何灭_怎样消灭蠓虫?
  8. mysql从一个表查询插入另一个表存在时更新_漫谈MySQL的锁机制
  9. React [Umi] history(API) 路由监听
  10. L1-1 PTA使我精神焕发 (5 分)