视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001 知道1 知道21 知道41 知道61 知道81 知道101 知道121 知道141 知道161 知道181 知道201 知道221 知道241 知道261 知道281
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
ReactNative列表ListView的用法
2020-11-27 22:33:28 责编:小采
文档

最近在学习ReactNative,本文介绍了ReactNative列表ListView的用法,分享给大家,也给自己留个笔记

ListView

在Android中,如果我们需要显示一个ListView,有两项是比不可少的,首先是ListView的数据源,其次是ListView每个item的样式。ReactNative中一样。首先我们来看一个简单的例子:

 constructor(props) {
 super(props);
 var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
 this.state = {
 dataSource: ds.cloneWithRows(['row 1', 'row 2']),
 };
 },

 render() {
 return (
 <ListView
 dataSource={this.state.dataSource}
 renderRow={(rowData) => <Text>{rowData}</Text>}
 />
 );
 },

在render()中,我们渲染一个ListView,在ListView的属性中,我们指定了dataSource和renderRow,这两个属性分别代表ListView的数据源和渲染的每一行。

dataSource

如果我们要创建一个数据源,最基本的方法就是创建一个ListView.DataSource数据源,然后通过cloneWithRows方法为其传递一个数组。

其中提供给数据源的rowHasChanged函数可以告诉ListView它是否需要重绘一行数据,即数据是否发生了改变,即在需要重绘界面的时候会进行判断,如果之前页面中的改行数据没有发生变化,则不再进行重绘,否则进行重绘。

如上述代码,我们对数据源设置数据时直接传入一个数组,当然我们也可以通过一个获取数据的方法,在设置数据的时候调用方法即可:

 constructor(props){
 super(props);
 var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
 this.state = {
 dataSource: ds.cloneWithRows(this._genRows()),
 };
 }

 _genRows(){
 const dataBlob = [];
 for(let i = 0 ; i< 200 ; i ++ ){
 dataBlob.push("aa"+i);
 }
 return dataBlob;
 }

这样通过方法获取数据,方便我们进行一些逻辑的处理。

renderRow

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

该属性需要传入一个方法,该方法如上所示,他会从数据源中接受一条数据,以及他和他所在的section的Id,返回一个可渲染的组件来为这行数据进行渲染,默认情况下参数中的数据就是放进数据源中的数据本身,不过也可以提供一些转换器。

如果某一行正在被高亮(通过调用highlightRow函数),ListView会得到相应的通知。当一行被高亮时,其两侧的分割线会被隐藏。行的高亮状态可以通过调用highlightRow(null)来重置。

 _renderRow(rowData, sectionID, rowID){
 return (
 <View>
 <Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
 </View>
 );
 }

 render() {
 return (
 <ListView
 dataSource={this.state.dataSource}
 renderRow={this._renderRow}
 />
 );
 },

因为renderRow中的方法会自动接受从数据源中的一条数据,因此我们可以通过调用外部方法的方式进行实现,同时只需要在外部方法的参数中传入我们需要从数据源中获取的数据即可,如上代码所示。

当我们需要实现比较复杂的布局时,也可以通过导入外部组件的方式作为ListView的每一行的样式。

例如我们自定义了一个组件Item_MyListView,我们需要在文件开头通过import方式将其导入到当前组件中:

 import Item_MyListView from './Item_MyListView';

然后就可以通过导入的名称直接使用我们导入的组件了:

 _renderRow(rowData, sectionID, rowID){
 return (
 <TouchableOpacity onPress={this._pressRow}>
 <View>
 <Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
 <Item_MyListView></Item_MyListView>
 </View>
 </TouchableOpacity>
 );
 }

ListView的点击

当我们需要给ListView的每一行添加点击事件时,只需要在其外层包裹一层TouchableOpacity或者TouchableHighlight,定义好onPress方法即可。

如下代码所示:

 _pressRow(rowID){
 alert("hellow"+rowID);
 }

 _renderRow(rowData, sectionID, rowID){
 return (
 <TouchableOpacity onPress={()=>this._pressRow(rowID)}>
 <View>
 <Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
 <Item_MyListView info={rowData}></Item_MyListView>
 </View>
 </TouchableOpacity>
 );
 }

需要注意的是,在ListView的renderRow属性中调用_renderRow一定要绑定this,否则onPress中的this就会指向错误,如下所示:

代码如下:
 <ListView dataSource={this.state.dataSource} renderRow={this._renderRow.bind(this)}/>
 

完整代码如下所示:

import React,{
 View,
 Text,
 TouchableOpacity,
 ListView,
} from 'react-native';

import Item_MyListView from './Item_MyListView';

export default class SecondPageComponent extends React.Component{

 constructor(props){
 super(props);
 var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
 this.state = {
 dataSource: ds.cloneWithRows(this._genRows()),
 };


 }

 _genRows(){
 const dataBlob = [];
 for(let i = 0 ; i< 200 ; i ++ ){
 dataBlob.push("aa"+i);
 }
 return dataBlob;
 }

 _pressRow(rowID){
 alert("hellow"+rowID);
 }

 _renderRow(rowData, sectionID, rowID){
 return (
 <TouchableOpacity onPress={()=>this._pressRow(rowID)}>
 <View>
 <Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
 <Item_MyListView info={rowData}></Item_MyListView>
 </View>
 </TouchableOpacity>
 );
 }


 render(){
 return (
 <View style={{flex:1,}}>
 <ListView dataSource={this.state.dataSource} renderRow={this._renderRow.bind(this)}/>
 </View>
 );
 }
}

 其中Item_MyListView只是随意定义了一个组件,没什么实际意义,就不再展示。

最终效果如下图所示:


下载本文
显示全文
专题