React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析


Posted in Javascript onJanuary 06, 2020

本文实例讲述了React Native中ScrollView组件轮播图与ListView渲染列表组件用法。分享给大家供大家参考,具体如下:

1、Scroll View

ScrollView是React Native提供的滚动视图组件,渲染一组视图,用户可以进行滑动响应交互,其常用属性如下:

滚动的偏移量:通过event.nativeEvent.contentOffset.x可以得到水平偏移量。

  • horizontal={bool},属性为true时,所有子视图在水平方向排列,否则在纵向排列。默认为false。
  • pagingEnabled={bool},属性为true时,滚动会停留在视图尺寸整数倍位置上,即正好显示某个视图,默认为false
  • scrollEnabled={bool},值为false时,视图不能滚动,默认true
  • showsHorizontalScrollIndicator={bool},值为true在滚动时会在屏幕底部显示一个滚动条,默认true
  • showsVerticalScrollIndicator={bool},值为true在滚动时显示垂直方向的滚动条,默认true。
  • keyboardDismissMode="none"/"on-drag",滑动视图时是否隐藏软键盘,默认none不隐藏。
  • onContentChange={function},当ScrollView视图大小发生变化时调用函数。
  • onScroll={function},当滚动视图时调用函数。
  • onMomentumScrollStart={function},滚动开始调用函数。
  • onMomentumScrollEnd={function},滚动结束时调用函数。

组件所属的方法有:

  • scrollTo({x:num,y:num,animated:bool}),组件视图滚动到指定x,y位置,第三个参数为是否启用动画
  • scrollToEnd({animated:bool}),滚动到视图末尾。

例如利用ScrollView来实现一个Banner轮播:

React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析

页面结构如下:

<View style={styles.banner}>
 <ScrollView ref="scrollView"   horizontal={true}
       pagingEnabled={true} showsHorizontalScrollIndicator={false}
       onMomentumScrollEnd={(e)=>this.slide(e)}
       onScrollBeginDrag={()=>{this.stopTimer()}}   //用户拖拽时停止自动轮播
       onScrollEndDrag={()=>{this.setTimer()}}    //拖拽结束后开始自动切换
 >
  {/*渲染轮播图片*/}
  {this.renderBanner()}
 </ScrollView>
 <View style={styles.indicateBar}>
  {/*渲染底部指示标签点*/}
  {this.renderIndicate()}
 </View>
</View>

利用map遍历数据数组zodiac,将图片渲染到页面

renderBanner(){
 return zodiac.map((item,index)=>
  <Image key={index} source={{uri:'asset:/zodiac/'+item.image+'.jpg'}} style={styles.itemImage} />
 )
}

在底部渲染指示点:

renderIndicate(){
 let jsx=[];
 for (let i=0;i<zodiac.length;i++){
  //判断是否为当前页,若为当前页则指示点color为蓝色,否则为白色
  if (i===this.state.pageIndex){
   jsx.push(<Text key={i} style={{fontSize:15,color:'#5cb0ff'}}>●</Text>)
  }else {
   jsx.push(<Text key={i} style={{fontSize:15,color:'#ffffff'}}>●</Text>)
  }
 }
 return jsx;
}

当用户滑动结束时触发ScrollView的onMomentumScrollEnd方法,调用slide函数,并传递event参数给slide。通过计算得出用户滑到的当前页的索引pageIndex,其中页码的计算就是将x偏移量除以每个视图的宽度然后取整

slide(e){
 let offset=e.nativeEvent.contentOffset.x;      //获取x偏移量
 let index=Math.floor(offset/DevWidth);       //通过偏移量计算出当前页码
 this.setState({
  pageIndex:index
 })
}

设置定时器让视图自动更换,通过setInterval让pageIndex隔一段时间自动+1,然后让图片偏移到页码对应的图片,令页面索引乘以每个页面宽度即为当前页面对应的偏移量:

setTimer(){
 this.timer=setInterval(()=>{
  this.setState((preState)=>{           //更新pageIndex
   if(preState.pageIndex>=(zodiac.length-1)){   //如果页码达到上界则归零
    return {pageIndex:0}
   }else {
    return {pageIndex:preState.pageIndex+1}        //否则页码加一
   }
  });
  // 让图片偏移到页码所对应的页面
  let offset=this.state.pageIndex*DevWidth;  
  this.refs.scrollView.scrollTo({x:offset,y:0,animated:true});
 },2000)
}

在组件销毁时清除定时器

componentWillUnmount() {
 clearInterval(this.timer);
}

2、List View

<ListView>用于将一组相同类型的数据渲染到页面上,你只需要定义好数据源与单个组件如何渲染,它便会将所有数据渲染完成。例如将如下左边json数据渲染为右边icon列表:

React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析 React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析

使用步骤如下

1、定义数据源,在constructor中初始化state,创建一个DataSource对象,在state中定义数据源iconSource为外部导入的json数据icons,格式如下:

let icons=require('./mockdata/icons.json').data;
constructor(props){
 super(props);
 let dataSource = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2});
 this.state={
  iconSource:dataSource.cloneWithRows(icons),
 }
}

其中{rowHasChaged:(r1,r2)=>r1!==r2},是告诉ListView当数据源变化时再重新渲染。

2、在页面使用<ListView>,设置数据源dataSource,内部样式contentContainerStyle,每个元素的渲染方式renderRow为renderIcon

<ListView dataSource={this.state.iconSource} contentContainerStyle={styles.iconList}
     renderRow={this.renderIcon}
/>

3、实现渲染函数renderIcon,默认传入四个参数:

  • rowData:每个元素对应的数据
  • sectionId:元素所属分区
  • rowId:元素的id
  • highlightRow:通过调用此方法可以使某一行处于高亮

在renderIcon函数中定义每一个icon图标的渲染的方式,并返回JSX:

renderIcon(rowData,sectionId,rowId,highlightRow){
 return(
  <TouchableOpacity activeOpacity={0.5}>
   <View key={rowId} style={styles.iconItem}>
    <Image style={styles.iconImg} source={{uri:'mipmap/'+rowData.image}} />
    <Text style={styles.iconTitle}>{rowData.title}</Text>
   </View>
  </TouchableOpacity>
 )
}

3、使用ListView渲染二维数据

以上例子中的data是个一维数组,数组每个元素中包含title与image两个字段,如果data是个二维数组,例如

React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析 React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析

其中data数组的一维元素中包含title与cars,而cars又是一个数组。使用ListView将其渲染为上面右图所示按首字母分类的列表。

存储原理:

ListView使用DataBlob来存储二维数据,其结构如下:

React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析 

DataBlob按照一定的格式组织二维数据,如上左图。DataBlob首先存储数组的第一维section并为其分配ID,例如将上面的一维数组的"title":"A",存储为DataBlob[0]="title":"A",分配sectionID为0,"title":"B",存储为DataBlob[1]="title":"B",分配ID为1......以此类推。

之后再存储数组的第二维row,例如"cars":[{"name":"奥迪","icon": "m_9_100.png"}],它的第一维sectionID为0,第二维rowID为2,将其存储为DataBlob[0:2]={"name":"奥迪","icon": "m_9_100.png"}。

ListView使用步骤如下:

1、设置数据源

与一维ListView使用类似,首先在constructor中设置state为DataSource对象:

this.state={
 carData:new ListView.DataSource({
  getSectionData:(dataBlob,sectionID)=>dataBlob[sectionID],  //设置sectionData获取方式
  getRowData:(dataBlob,sectionID,rowID)=>dataBlob[sectionID+':'+rowID],  //设置rowData获取方式
  sectionHeaderHasChanged:(s1,s2)=>s1!==s2,  //设置section更新方式
  rowHasChanged:(r1,r2)=>r1!==r2        //设置row更新方式
 })
}

在新建DataSource对象时需要传递四个函数参数

  • getSectionData:定义获取section的方式,它接收两个参数,dataBlob对象与sectionId,例如要获取上面提到的DataBlob[0]="title":"A" ,则通过dataBlob[sectionID]就可以返回"title":"A"。
  • getRowData:获取row的方式,同理,通过DataBlob[0:2]可以得到{"name":"奥迪","icon": "m_9_100.png"}
  • sectionHeaderHasChanged:定义section什么时候更新,接收两个参数s1,s2分别为前后两个状态,不同时才会重新渲染section
  • rowHasChanged:定义row什么时候更新

2、在页面中使用ListView

使用List View时设置其数据源及渲染方法

<ListView style={styles.carList}
     dataSource={this.state.carData}        //定义数据源
     renderRow={this.renderCarRow}         //定义row的渲染方法
     renderSectionHeader={this.renderCarSection}  //定义SectionHeader渲染方法
/>

3、实现渲染方法,方法默认会传入参数rowData与sectionData

renderCarSection(sectionData){
 return(
  <View style={styles.sectionBar}>
   <Text style={styles.sectionTxt}>{sectionData}</Text>
  </View>
 )
}
renderCarRow(rowData){
 return(
  <TouchableOpacity activeOpacity={0.5}>
   <View style={styles.carItem}>
    <Image source={{uri:'asset:/cars/'+rowData.icon}} style={styles.carImg} />
    <Text style={styles.carTitle}>{rowData.name}</Text>
   </View>
  </TouchableOpacity>
 )
}

4、将数据放入dataBlob

在组件挂载完成后将数据按照格式放入dataBlob并更新数据源,使数据加载到页面

componentDidMount() {
 this.loadCarData();
}
loadCarData(){
 let dataBlob={},      //dataBlob对象
  sectionIDs=[],      //sectionID数组
  rowIDs=[],        //rowID数组
  cars=[];
 for (let i=0;i<carData.length;i++){    //循环遍历二维数据carData  
  sectionIDs.push(i);           //将一维下标i当作sectionID
  dataBlob[i]=carData[i].title;      //将section数据放入dataBlob第一维
  rowIDs[i]=[];              //初始化rowID数组的每个元素为一个数组
  cars=carData[i].cars;          //拿到每个section下的cars数组
  for (let j=0;j<cars.length;j++){    //遍历section下的cars数组
   rowIDs[i].push(j);          //二维数组rowIDs[i][j]
   dataBlob[i+':'+j]=cars[j];      //将每行row数据放入dataBlob[i:j]第二维
  }
 }
 this.setState({              //更新state中的数据源carData,需要传入三个参数
  carData:this.state.carData.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs)
 })
}

希望本文所述对大家React程序设计有所帮助。

Javascript 相关文章推荐
使两个iframe的高度与内容自适应,且相等
Nov 20 Javascript
一个JQuery写的点击上下滚动的小例子
Aug 27 Javascript
Javascript中的apply()方法浅析
Mar 15 Javascript
easyui导出excel无法弹出下载框的快速解决方法
Nov 10 Javascript
Javascript 两种刷新方法以及区别和适用范围
Jan 17 Javascript
详解Angualr 组件间通信
Jan 21 Javascript
快速了解Node中的Stream流是什么
Feb 13 Javascript
在Vue mounted方法中使用data变量详解
Nov 05 Javascript
ant design实现圈选功能
Dec 17 Javascript
js实现移动端吸顶效果
Jan 08 Javascript
Node.js中文件系统fs模块的使用及常用接口
Mar 06 Javascript
Vue 中获取当前时间并实时刷新的实现代码
May 12 Javascript
Vue-CLI与Vuex使用方法实例分析
Jan 06 #Javascript
Vue前端项目部署IIS的实现
Jan 06 #Javascript
Vue学习之常用指令实例详解
Jan 06 #Javascript
Vue学习之组件用法实例详解
Jan 06 #Javascript
Vue+abp微信扫码登录的实现代码示例
Jan 06 #Javascript
Vue学习之axios的使用方法实例分析
Jan 06 #Javascript
vue 微信扫码登录(自定义样式)
Jan 06 #Javascript
You might like
如何使用Strace调试工具
2013/06/03 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
PHP小偷程序的设计与实现方法详解
2016/10/15 PHP
php生成word并下载代码实例
2019/03/15 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
在IE和VB中支持png图片透明效果的实现方法(vb源码打包)
2011/04/01 Javascript
JQuery文本框高亮显示插件代码
2011/04/02 Javascript
用javascript作一个通用向导说明
2011/08/30 Javascript
jquery处理json数据实例分析
2014/06/03 Javascript
jQuery元素选择器用法实例
2014/12/23 Javascript
JavaScript原生对象常用方法总结(推荐)
2016/05/13 Javascript
JavaScript实现打开链接页面的方式汇总
2016/06/02 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
JS轮播图中缓动函数的封装
2020/11/25 Javascript
基于bootstrap按钮式下拉菜单组件的搜索建议插件
2017/03/25 Javascript
使用D3.js创建物流地图的示例代码
2018/01/27 Javascript
jsonp实现百度下拉框功能的方法分析
2019/05/10 Javascript
JS求1到任意数之间的所有质数的方法详解
2019/05/20 Javascript
js实现列表按字母排序
2020/08/11 Javascript
JavaScript 生成唯一ID的几种方式
2021/02/19 Javascript
python实现简单socket程序在两台电脑之间传输消息的方法
2015/03/13 Python
Python实现查找二叉搜索树第k大的节点功能示例
2019/01/24 Python
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
python调试神器PySnooper的使用
2019/07/03 Python
Django使用Jinja2模板引擎的示例代码
2019/08/09 Python
Python 串口通信的实现
2020/09/29 Python
大学生活动策划方案
2014/02/10 职场文书
小学数学课题方案
2014/06/15 职场文书
大学生就业意向书
2015/05/11 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
《植物妈妈有办法》教学反思
2016/02/23 职场文书
python正则表达式re.search()的基本使用教程
2021/05/21 Python
详解CSS伪元素的妙用单标签之美
2021/05/25 HTML / CSS
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers