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 相关文章推荐
js 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
Apr 10 Javascript
javascript:json数据的页面绑定示例代码
Jan 26 Javascript
Node.js中require的工作原理浅析
Jun 24 Javascript
JS实现的仿淘宝交易倒计时效果
Nov 27 Javascript
JavaScript判断按钮被点击的方法
Dec 13 Javascript
基于JavaScript如何制作遮罩层对话框
Jan 26 Javascript
Bootstrap按钮组简单实现代码
Mar 06 Javascript
React中ES5与ES6写法的区别总结
Apr 21 Javascript
js阻止默认右键的下拉菜单方法
Jan 02 Javascript
JS点击动态添加标签、删除指定标签的代码
Apr 18 Javascript
Angular服务Request异步请求的实例讲解
Aug 13 Javascript
JavaScript实现图片的放大缩小及拖拽功能示例
May 14 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
Window 7/XP 安装Apache 2.4与PHP 5.4 的过程详解
2013/06/02 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
JS遮罩层效果 兼容ie firefox jQuery遮罩层
2010/07/26 Javascript
一些实用的jQuery代码片段收集
2011/07/12 Javascript
jquery中dom操作和事件的实例学习 下拉框应用
2011/12/01 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
2013/12/31 Javascript
判断复选框是否被选中的两种方法
2014/06/04 Javascript
超炫的jquery仿flash导航栏特效
2014/11/11 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
JS实现星星评分功能实例代码(两种方法)
2016/06/09 Javascript
jQuery获取剪贴板内容的方法
2016/06/16 Javascript
JavaScript的字符串方法汇总
2016/07/31 Javascript
js 判断登录界面的账号密码是否为空
2017/02/08 Javascript
bootstrap select插件封装成Vue2.0组件
2017/04/17 Javascript
bootstrap table实现x-editable的行单元格编辑及解决数据Empty和支持多样式问题
2017/08/10 Javascript
详解vue更改头像功能实现
2019/04/28 Javascript
深入探索VueJS Scoped CSS 实现原理
2019/09/23 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
vue实现购物车功能(商品分类)
2020/04/20 Javascript
nuxt.js 在middleware(中间件)中实现路由鉴权操作
2020/11/06 Javascript
用python分割TXT文件成4K的TXT文件
2009/05/23 Python
Python入门篇之函数
2014/10/20 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
Flask框架学习笔记之使用Flask实现表单开发详解
2019/08/12 Python
Pandas中DataFrame基本函数整理(小结)
2020/07/20 Python
Python 整行读取文本方法并去掉readlines换行\n操作
2020/09/03 Python
毕业实习评语
2014/02/10 职场文书
银行批评与自我批评
2014/02/10 职场文书
建筑安全员岗位职责
2015/02/15 职场文书
未中标通知书
2015/04/17 职场文书
2015年检验员工作总结范文
2015/04/30 职场文书
2019开业庆典剪彩仪式主持词!
2019/07/22 职场文书
Nginx配置并兼容HTTP实现代码解析
2021/03/31 Servers
python3 hdf5文件 遍历代码
2021/05/19 Python