RN开发京东客户端首页(三)——轮播图的实现
1.相关控件调研
目前在Github开源的轮播图控件,个人认为做得比较好的,一个是react-native-swiper(https://github.com/leecade/react-native-swiper),一个是react-native-viewpager(https://github.com/race604/react-native-viewpager),而经过试用发现,react-native-swiper虽然效果和样式较多、控制方便,但在将它缩小为一个固定高度的视图时,其底部的指示符号(即几个点,如下图)就不见了,所以最终我推荐使用react-native-viewpager,简单好用!
2.添加相关文件
下来我们将素材和相关的库导入项目当中,其中,react-native-viewpager的添加方法如下:
npm i -d react-native-viewpager --save
然后在工程的images文件夹中创建banner文件夹,其中放入4个jpg文件:
1 const BANNER_IMGS = [ 2 require('../images/banner/1.jpg'), 3 require('../images/banner/2.jpg'), 4 require('../images/banner/3.jpg'), 5 require('../images/banner/4.jpg') 6 ];
3.构建ViewPager
经过分析,我们可以看到,首页轮播图的样式十分简单,只需要指定高度,而水平方向,利用flex:1进行拉伸
但由于react-native-viewpager作者在构建这个控件的时候,应该是用到一些变量进行控制,并提供了一种方法,用于创建图片数据源,所以,如果需要使用react-native-viewpager必须在构造函数中进行初始化,具体代码如下:
接着,我们在HomePage类的定义前,创建一个数组常量,用于存放图片:
1 constructor(props) { 2 super(props); 3 // 用于构建DataSource对象 4 var dataSource = new ViewPager.DataSource({ 5 pageHasChanged: (p1, p2) => p1 !== p2, 6 }); 7 // 实际的DataSources存放在state中 8 this.state = { 9 dataSource: dataSource.cloneWithPages(BANNER_IMGS) 10 } 11 }
而在render函数中,ViewPager的使用也是相当简单的,具体写法如下:
1 <ViewPager 2 style={{height:130}} 3 dataSource={this.state.dataSource} 4 renderPage={this._renderPage} 5 isLoop={true} 6 autoPlay={true} 7 />
其中:
style:样式,和其他控件设置方式类似
dataSource:即在构造函数中利用dataSource对象和图片数组常量,创建的真实dataSource
renderPage:方法类型,返回一段JSX,用于指定ViewPager每页的内容,该方法写法如下,切忌根据WebStorm的提示加上static!:
1 _renderPage(data, pageID) { 2 return ( 3 <Image 4 source={data} 5 style={styles.page}/> 6 ); 7 }
isLoop:是否循环播放,按照示例代码设置即可
autoPlay:是否自动播放,按照示例代码设置即可
locked: 设置为true即禁用ViewPager的点击
onChangePage: 页面切换的回调函数
renderPageIndicator: 自定义指示器样式的渲染
animation:如果觉得原始的效果不满意,可以在这个字段中设置一个函数,自定义动画效果
当然,要记得给ViewPager和其中的item添加样式:
1 const styles = StyleSheet.create({ 2 page: { 3 flex: 1, 4 height: 130, 5 resizeMode: 'stretch' 6 } 7 });
保存一下代码,在模拟器上看看效果吧
工程源码及资源文件:https://github.com/yuanguozheng/JdApp
本次Commit:https://github.com/yuanguozheng/JdApp/commit/2d1741bef1c7908c9e0d2f52c23210e8de2fcc7a