写 RN 也有段时间了,今天抽空就对 RN 当中的 ListView 进行一个简单介绍,主要介绍使用当中的一些坑。
写一个简单的 ListView
1 | class MyComponent extends Component { |
以上代码就可以绘制一个简单的 ListView 了,但是我们需要注意dataSource: ds.cloneWithRows(['row 1', 'row 2'])这一行,因为我们的数据一般都是网络请求来的,所以我们一般可能会写成这样
1 | listData = []; |
然而你发现你的 ListView 并没有更新,还是一片空白,当我们把dataSource: ds.cloneWithRows(this.listData)这一行改成dataSource: ds.cloneWithRows(this.listData.slice())你会发现问题解决了,why?
这是因为这样只是一个浅拷贝,虽然数组内容发生了变化,但是ds.cloneWithRows接收到的数据没有发生变,故页面会刷新。当我们用slice时,给它返回一个新值,这样界面就会重新刷新渲染。
写一个带 Section 的 ListView
要写一个带 Section 的 ListView 主要是针对数据源的改造。
DataSource 构造函数可以接受下列四种参数(都是可选):
1 | getRowData(dataBlob, sectionID, rowID); |
如果不提供 getRowData 和 getSectionHeaderData 方法,使用 defaultGetRowData 和 defaultGetSectionHeaderData 来提取数据,默认的提取函数可以处理的数据结构如下:
1 | { sectionID_1: { rowID_1: rowData1, ... }, ... } |
我们用第二种数据结构来实现:
1 | class MyComponent extends Component { |
需要注意的是cloneWithRowsAndSections(dataBlob, sectionIdentities, rowIdentities)方法当中的参数也需要是一个新值,所以rowIdentities参数的数据也需要slice()一下,回传一个新值。
当需要将 sectionHeader 的样式显示出来,还需要在 render 当中添加关于 header 渲染的代码
1 | render() { |
这样一个带 section 的 ListView 就写出来了。
一些注意事项
- React Native 不支持随 ListView 滚动的 Header,如果需要,请在每个 section 当中的第一个 Item 当中添加
- 如果 ListView 要下拉一下才显示出来,请设置 ListView 的属性
removeClippedSubviews={false} - 如果在 iOS 设备上 ListView 距离顶部导航栏有距离,请设置 ListView 的属性
automaticallyAdjustContentInsets={false}