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 对Cookie 操作的封装小结
Dec 31 Javascript
JS实现在Repeater控件中创建可隐藏区域的代码
Sep 16 Javascript
JQuery动态给table添加、删除行 改进版
Jan 19 Javascript
js函数的延迟加载实现代码
Oct 11 Javascript
仿百度联盟对联广告实现代码
Aug 30 Javascript
完美兼容各大浏览器的jQuery插件实现图片切换特效
Dec 12 Javascript
webpack常用配置项配置文件介绍
Nov 07 Javascript
AngularJS实现表单验证功能详解
Oct 12 Javascript
vue中路由参数传递可能会遇到的坑
Dec 07 Javascript
解决node修改后需频繁手动重启的问题
May 13 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
Dec 04 Javascript
JavaScript数组常用的增删改查与其他属性详解
Oct 13 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
php模板之Phpbean的目录结构
2008/01/10 PHP
php中在PDO中使用事务(Transaction)
2011/05/14 PHP
Eclipse中php插件安装及Xdebug配置的使用详解
2013/04/25 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
做网页的一些技巧(续)
2007/02/01 Javascript
Jquery为单选框checkbox绑定单击click事件
2012/12/18 Javascript
Js日期选择自动填充到输入框(界面漂亮兼容火狐)
2013/08/02 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
2016/05/26 Javascript
AngularJS ng-style中使用filter
2016/09/21 Javascript
javascript代码调试之console.log 用法图文详解
2016/09/30 Javascript
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
AngularJS框架的ng-app指令与自动加载实现方法分析
2017/01/04 Javascript
vue-for循环嵌套操作示例
2019/01/28 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
关于小程序优化的一些建议(小结)
2020/12/10 Javascript
Python yield使用方法示例
2013/12/04 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
python实现录音小程序
2020/10/26 Python
Python将string转换到float的实例方法
2019/07/29 Python
python接口自动化如何封装获取常量的类
2019/12/24 Python
Opencv求取连通区域重心实例
2020/06/04 Python
英国当代时尚和街头服饰店:18montrose
2018/12/15 全球购物
德国珠宝和配件商店:Styleserver
2021/02/23 全球购物
Python里面如何实现tuple和list的转换
2012/06/13 面试题
信息系统专业个人求职信范文
2013/12/07 职场文书
企业承诺书格式
2014/05/21 职场文书
大型演出策划方案
2014/05/28 职场文书
党员干部群众路线个人整改措施
2014/09/18 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
老公出轨后的保证书
2015/05/08 职场文书
2016五一劳动节慰问信
2015/11/30 职场文书
《日月潭》教学反思
2016/02/20 职场文书
详解Vue slot插槽
2021/11/20 Vue.js