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 相关文章推荐
JavaScript中的常见问题解决方法(乱码,IE缓存,代理)
Nov 28 Javascript
js设置cookie过期当前时间减去一秒相当于立即过期
Sep 04 Javascript
jquery获得同源iframe内body下标签的值的方法
Sep 25 Javascript
js正则表达式replace替换变量方法
May 21 Javascript
在Javascript操作JSON对象,增加 删除 修改的简单实现
Jun 02 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
Aug 19 Javascript
JavaScript对象引用与赋值实例详解
Mar 15 Javascript
Bootstrap下拉菜单Dropdowns的实现代码
Mar 17 Javascript
vue element table 表格请求后台排序的方法
Sep 28 Javascript
解决Vue动态加载本地图片问题
Oct 09 Javascript
Vue学习之常用指令实例详解
Jan 06 Javascript
vue-cli3使用mock数据的方法分析
Mar 16 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
Uchome1.2 1.5 代码学习 common.php
2009/04/24 PHP
奉献出一个封装的curl函数 便于调用(抓数据专用)
2013/07/22 PHP
PHP登录环节防止sql注入的方法浅析
2014/06/30 PHP
PHP准确取得服务器IP地址的方法
2015/06/02 PHP
PHP常用的小程序代码段
2015/11/14 PHP
JavaScript CSS修改学习第二章 样式
2010/02/19 Javascript
锋利的jQuery 要点归纳(一) jQuery选择器
2010/03/21 Javascript
按钮接受回车事件的三种实现方法
2014/06/06 Javascript
checkbox选中与未选中判断示例
2014/08/04 Javascript
js实现简单排列组合的方法
2016/01/27 Javascript
在页面中输出当前客户端时间javascript实例代码
2016/03/02 Javascript
一次$.getJSON不执行的简单记录
2016/07/19 Javascript
javaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序整理总结
2016/10/10 Javascript
AngularJS实现根据不同条件显示不同控件
2017/04/20 Javascript
微信小程序之蓝牙的链接
2017/09/26 Javascript
webpack中的热刷新与热加载的区别
2018/04/09 Javascript
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
2020/03/06 Javascript
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
python验证码识别教程之滑动验证码
2018/06/04 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
2018/12/12 Python
python使用adbapi实现MySQL数据库的异步存储
2019/03/19 Python
Python实现一个带权无回置随机抽选函数的方法
2019/07/24 Python
Python更新所有已安装包的操作
2020/02/13 Python
IE浏览器单独写CSS样式的几种方法
2014/10/14 HTML / CSS
HTML5有哪些新特征
2015/12/01 HTML / CSS
世界第一曲奇连锁店:Mrs. Fields Cookies
2017/02/04 全球购物
Bally巴利中国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/10/09 全球购物
美国购买体育赛事门票网站:TicketCity
2019/03/06 全球购物
餐饮管理自我介绍信
2014/01/15 职场文书
优秀教师的感人事迹
2014/02/04 职场文书
理工学院学生自我鉴定
2014/02/23 职场文书
高一学年自我鉴定范文(3篇)
2014/09/26 职场文书
甲午大海战观后感
2015/06/02 职场文书
初中数学课堂教学反思
2016/02/17 职场文书
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python