React Native 系列(七) -- ListView
前言
本系列是基于React Native版本号0.44.3写的。几乎所有的App都使用了ListView这种组件,这篇文章将学习RN中ListView的平铺样式和分组样式。
ListView平铺样式
ListView内部是通过ListViewDataSource这个对象显示数据的,因此使用ListView的时候需要创建一个ListViewDataSource对象。ListViewDataSource构造方法创建对象的时候可以选择性出入4个参数,描述怎么提取cell,怎么刷新cell这些参数都是函数,当产生对应事件的时候,会自动调用对应函数
构造函数可以接收以下四种参数(都是函数): getRowData(dataBlob, sectionID, rowID); // 怎么获取行数据
getSectionHeaderData(dataBlob, sectionID); // 获取没组头数据
rowHasChanged(prevRowData, nextRowData); // 决定什么情况行数据才发生改变,当行数据发生改变,就会绘制下一行
sectionHeaderHasChanged(prevSectionData, nextSectionData); // 决定什么情况头部数据才会发生改变,当头部数据发生改变,就会绘制下一个组
ListViewDataSource为ListView组件提供高性能的数据处理和访问。我们需要调用clone方法从原始输入数据中抽取数据来创建ListViewDataSource对象。要更新
datasource中的数据,请(每次都重新)调用cloneWithRows方法(如果用到了section,则对应cloneWithRowsAndSections方法)clone方法会自动提取新数据并进行逐行对比(使用rowHasChanged方法中的策略),这样ListView就知道哪些行需要重新渲染了。
平铺样式使用步骤
创建数据源
- 因为改变数据的时候需要刷新界面,因此可以利用
setState - 获取
ListViewDataSource使用ListView.DataSource ListViewDataSource构造方法:决定ListView怎么去处理数据,需要传入一个对象,这个对象有四个可选属性,都是方法。- 初始化
ListViewDataSource的时候,如果不需要修改提取数据的方式,只需要实现rowHasChanged,告诉什么时候刷新下一行 - 默认
ListViewDataSource有提取数据方式,可以使用默认提取方式。
// 构造
constructor(props) {
super(props);
// 初始状态
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
}
- 因为改变数据的时候需要刷新界面,因此可以利用
给数据源设置数据
// 构造
constructor(props) {
super(props);
// 初始状态
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row1', 'row2'])
}
}
实现数据源方法,确定cell
- 这个方法会自动传入四个参数(rowData, sectionID, rowID, highlightRow)
- rowData: 行数据
- sectionID: 当前行所在的组id
- rowID: 当前行所在的行id
- highlightRow: 高亮函数
render() {
return (
<ListView style={{marginTop: 20}}
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
/>
);
} _renderRow(rowData, sectionID, rowID, highlightRow){
return (
<View>
<Text>{rowData}</Text>
</View>
);
}
ListView分割线
运行上面的代码,你会发现ListView没有分割线,我们可以添加分割线:
render() {
return (
<ListView style={{marginTop: 20}}
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
renderSeparator={this._renderSeparator.bind(this)}
/>
);
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
return (
<View style={{height:1,backgroundColor:'black'}}>
</View>
)
}
ListView头部视图
_renderHeader(){
return (
<View style={[{height:30}, {backgroundColor:'red'},{justifyContent: 'center'}]}>
<Text style={[{textAlign: 'center'}]}>头部视图</Text>
</View>
);
}
效果图:

ListView尾部视图
_renderFooter(){
return (
<View style={[{height: 30}, {backgroundColor: 'red'}, {justifyContent:'center'}]}>
<Text style={{textAlign: `center`}}>尾部视图</Text>
</View>
)
}
效果图:

ListView点击cell高亮
_renderRow(rowData, sectionID, rowID, highlightRow){
return (
<TouchableOpacity onPress={()=>{
AlertIOS.alert(rowID)
highlightRow(sectionID, rowID)
}}>
<View style={{height: 40}}>
<Text>{rowData}</Text>
</View>
</TouchableOpacity>
);
}
注意:需要导入TouchableOpacity和AlertIOS
ListView分组样式
有时候我们会遇到ListView分组样式,比如中国有多少个省,然后每个省又有多少个城市。
要想明白ListView是如何分组的,就需要知道ListView底层是如何获取组数据,行数据。
ListView分组原理
ListView默认支持3种格式的数据,只要按照这3种格式处理数据,就会自动获取数据,从而达到分组样式
默认的3种格式的数据:
// 格式一
[[row_0, row_1,...],[row_0, row_1,...],...]
// 格式二
{sectionID_0:{rowID_0, rowID_1, rowID_2, ...}, ...}
// 格式三
{sectionID_0:[rowID_0, rowID_1, ...], ...}
实现ListView分组样式步骤
创建数据源
var dataSource = new ListView.DataSource({
rowHasChanged:(r1,r2)=>r1 !== r2,
sectionHeaderHasChanged:(s1,s2)=>s1 !== s2
});
设置数据
- 不分组使用:
cloneWithRows() - 分组使用:
cloneWithRowsAndSections()
this.state = {
dataSource: ds.cloneWithRowsAndSections(Data)
}
- 不分组使用:
渲染
ListView
代码演练
这个例子我们使用了本地假数据,创建一个Data.json文件,它看起来是这样:
[
["section0-row0","section0-row1","section0-row2","section0-row3"],
["section1-row0","section1-row1","section1-row2","section1-row3"],
["section2-row0","section2-row1","section2-row2","section2-row3"],
["section3-row0","section3-row1","section3-row2","section3-row3"],
["section4-row0","section4-row1","section4-row2","section4-row3"],
["section5-row0","section5-row1","section5-row2","section5-row3"]
]
我们在index.ios.js里面引用Data.json
var Data = require('./Data.json')
然后就按照上述 实现ListView分组样式 步骤写:
var Data = require('./Data.json')
// 主组件
export default class RNDemoOne extends Component {
// 构造
constructor(props) {
super(props);
// 初始状态
var ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
});
this.state = {
dataSource: ds.cloneWithRowsAndSections(Data)
}
}
render() {
return (
<ListView style={{marginTop: 20}}
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
renderSeparator={this._renderSeparator.bind(this)} renderSectionHeader={this._renderSectionHeader.bind(this)}
/>
);
}
_renderSectionHeader(sectionData, sectionID){
return (
<View style={[{height: 40}, {backgroundColor:'red'}]}>
<View style={[{flex:1}, {justifyContent: 'center'}]}>
<Text style={{paddingLeft: 10}}>{sectionID}</Text>
</View>
</View>
)
}
_renderRow(rowData, sectionID, rowID, highlightRow){
return (
<TouchableOpacity onPress={()=>{
AlertIOS.alert(rowID)
highlightRow(sectionID, rowID)
}}>
<View style={{height: 40}}>
<Text>{rowData}</Text>
</View>
</TouchableOpacity>
);
}
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
return (
<View style={{height:1,backgroundColor:'black'}}>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
致谢
如果发现有错误的地方,欢迎各位指出,谢谢!
React Native 系列(七) -- ListView的更多相关文章
- React Native 系列(七)
前言 本系列是基于React Native版本号0.44.3写的.几乎所有的App都使用了ListView这种组件,这篇文章将学习RN中ListView的平铺样式和分组样式. ListView平铺样式 ...
- React Native的组件ListView
React Native的组件ListView类似于iOS中的UITableView和UICollectionView,也就是说React Native的组件ListView既可以实现UITableV ...
- 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信
http://blog.csdn.net/xiaominghimi/article/details/51586492 一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解R ...
- React Native 系列(一) -- JS入门知识
前言 本系列是基于React Native版本号0.44.3写的,最初学习React Native的时候,完全没有接触过React和JS,本文的目的是为了给那些JS和React小白提供一个快速入门,让 ...
- React Native 系列(二) -- React入门知识
前言 本系列是基于React Native版本号0.44.3写的,最初学习React Native的时候,完全没有接触过React和JS,本文的目的是为了给那些JS和React小白提供一个快速入门,让 ...
- React Native 系列(四) -- 布局
前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...
- React Native 系列(五) -- 组件间传值
前言 本系列是基于React Native版本号0.44.3写的.任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传.逆传已经通过通知传值. ...
- React Native 系列(六) -- PropTypes
前言 本系列是基于React Native版本号0.44.3写的.在我们之前的通过props实现组件间传值的时候,大家有没有发现在父组件传递值过去,在子控件获取props的时候没有提示,那么如何能实现 ...
- React Native 系列(八) -- 导航
前言 本系列是基于React Native版本号0.44.3写的.我们都知道,一个App不可能只有一个不变的界面,而是通过多个界面间的跳转来呈现不同的内容.那么这篇文章将介绍RN中的导航. 导航 什么 ...
随机推荐
- 搭建nexus私服(maven)
这里提供nexus的直接下载页面的链接: https://www.sonatype.com/download-oss-sonatype maven获取依赖jar包是从中央仓库获取,但很莫名的出现jar ...
- Student implements java.io.Serializable
package JBJADV003; public class Student implements java.io.Serializable { private String name; priva ...
- 第二章:2.8 通过Django 在web页面上面输出 “Hello word ”
1. 第一步:配置 guest 目录下面的 settings.py 文件, 将 sign应用添加到 guest项目中. 2. 在 guest目录下面,打开 urls.py 文件,添加 要打开的路由文件 ...
- Hibernate框架 主配置文件(Hibernate.cfg.xml) 映射配置 说明
Hibernate.cfg.xml 主配置文件中主要配置:数据库连接信息.其他参数.映射信息! 常用配置查看源码: hibernate-distribution-3.6.0.Final\project ...
- webpack2归纳总结
本文github仓库:https://github.com/Rynxiao/webpack2-learn 从v1迁移到v2 1. 配置类型 在webpack1的时候,主要是通过导出单个object来进 ...
- 《javascript 高级程序设计》笔记
1-4章 1.变量①.ECMAScript 变量是松散类型的,也就是说可以用来保存任何类型的数据.换句话说每个变量仅仅是一个用于保存值的占位符.②.如果在函数中使用var定义一个变量,那么这个变量在函 ...
- 阿里云VPC绑定EIP实现SNAT
阿里云VPC需要了解的几个问题 什么是VPC 虚拟私有网络(Virtual Private Network),能够帮助用户基于阿里云构建出一个隔离的网络环境.用户可以完全掌控自己的虚拟网络,包括选择自 ...
- django MVC模式 数据库的操作mysql
介绍:本节课我们继续学习djangoWEB框架的开发,这节课主要是学习如何访问数据库,django如何自动为我们创建好表结构等相关内容. 1.首先我们打开settings.py找到DATABASES关 ...
- JavaScript语法基础(1)
1.JavaScript是什么? 1)定义: JavaScript「JS」是一种高级的.动态的. 弱类型的.解释型的计算机编程脚本语言. 2)原理: 3)组成: 3大部分: ◆ ECMAScript: ...
- 移动端JS事件、移动端框架
一.移动端的操作方式和PC端是不同的,移动端主要是用手指操作,所以有特殊的touch事件,touch事件包括如下几个事件: 1.手指放到屏幕上时触发 touchstart 2.手指放在屏幕上滑动式 ...