React Native 系列(七) -- ListView

前言

本系列是基于React Native版本号0.44.3写的。几乎所有的App都使用了ListView这种组件,这篇文章将学习RNListView的平铺样式和分组样式。

ListView平铺样式

  • ListView内部是通过ListViewDataSource这个对象显示数据的,因此使用ListView的时候需要创建一个ListViewDataSource对象。
  • ListViewDataSource构造方法创建对象的时候可以选择性出入4个参数,描述怎么提取cell,怎么刷新cell
  • 这些参数都是函数,当产生对应事件的时候,会自动调用对应函数
  • ListViewDataSourceListView组件提供高性能的数据处理和访问。我们需要调用clone方法从原始输入数据中抽取数据来创建ListViewDataSource对象。
  • 要更新datasource中的数据,请(每次都重新)调用cloneWithRows方法(如果用到了section,则对应cloneWithRowsAndSections方法)clone方法会自动提取新数据并进行逐行对比(使用rowHasChanged方法中的策略),这样ListView就知道哪些行需要重新渲染了。

平铺样式使用步骤

  1. 创建数据源
    • 因为改变数据的时候需要刷新界面,因此可以利用setState
    • 获取ListViewDataSource使用ListView.DataSource
    • ListViewDataSource构造方法:决定ListView怎么去处理数据,需要传入一个对象,这个对象有四个可选属性,都是方法。
    • 初始化ListViewDataSource的时候,如果不需要修改提取数据的方式,只需要实现rowHasChanged,告诉什么时候刷新下一行
    • 默认ListViewDataSource有提取数据方式,可以使用默认提取方式。

2.给数据源设置数据

3.实现数据源方法,确定cell

  • 这个方法会自动传入四个参数(rowData, sectionID, rowID, highlightRow)
  • rowData: 行数据
  • sectionID: 当前行所在的组id
  • rowID: 当前行所在的行id
  • highlightRow: 高亮函数

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>
    );
}

注意:需要导入TouchableOpacityAlertIOS

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分组样式步骤

  1. 创建数据源 var dataSource = new ListView.DataSource({ rowHasChanged:(r1,r2)=>r1 !== r2, sectionHeaderHasChanged:(s1,s2)=>s1 !== s2 });
  2. 设置数据
    • 不分组使用: cloneWithRows()
    • 分组使用: cloneWithRowsAndSections()

    this.state = { dataSource: ds.cloneWithRowsAndSections(Data) }

  3. 渲染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,
    },
});

致谢

如果发现有错误的地方,欢迎各位指出,谢谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AndroidTv

我的2017年总结笔记整理

35711
来自专栏何俊林

Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程

前言:前一篇的mediaPlayer框架,对于各个模块的关系,得先从核心类MediaPlayer铺开,同样看下今天的Agenda: MediaPlayer从cr...

2905
来自专栏Android机动车

走进SurfaceView

最近在写视频播放器的时候用到了SurfaceView和MediaPlayer,在各个功能完成后,竟得意忘形,感觉自己又get到新技能,可以嘚瑟几天了,直到前两天...

1362
来自专栏学海无涯

Android开发之高德地图实现定位

在应用开发中,地图开发是经常需要使用的“组件”,Google Map虽然有官方教程,无奈用不起来,原因你懂的~~那么国内比较出名的是就是百度地图和高德地图,由于...

4094
来自专栏葡萄城控件技术团队

Wijmo 更优美的jQuery UI部件集:在对Wijmo GridView进行排序或者过滤时保留选择

许多客户面临这样的场景,他们希望在应用了排序或者过滤之后仍然将最终用户的行选状态保留。通常情况下,当我们在选择了任何行之后应用排序或者过滤会导致回传之后选择状态...

1899
来自专栏mukekeheart的iOS之旅

iOS学习—— UINavigationController的返回按钮与侧滑返回手势的研究

侧滑返回手势是从iOS7开始增加的一个返回操作,经历了两年时间估计iPhone用户大部分都已经忽略了屏幕左上角那个碍眼的back按钮了。之前在网上搜过有关侧滑...

9046
来自专栏更流畅、简洁的软件开发方式

【开源】QuickPager ASP.NET2.0分页控件V2.0.0.7 增加了一个js函数的分页方式。

     昨天在csdn上看到一个人提出来了一种分页的需求,大致是分页控件只负责绘制总页数、上一页、下一页等信息,然后在用户翻页的时候可以触发一个js函数,然后...

2399
来自专栏Objective-C

Swift-MVVM 简单演练(三)

2963
来自专栏iOS122-移动混合开发研究院

SVProgressHUD–比MBProgressHUD更好用的 iOS进度提示组件

简介 ? SVProgressHUD是简单易用的显示器,用于指示一个持续进行的任务的进度. 最新示例: 点击下载 快速入门 安装 通过Cocoapods pod...

3778
来自专栏双十二技术哥

深入Weex系列(六)Weex渲染流程分析

在前两篇文章中我们结合源码学习了Module、Component的注册、调用、回调等流程,相信大家一定收获颇多,对Weex的理解也一定愈加深入。

1265

扫码关注云+社区

领取腾讯云代金券