在RN官方文档中,对ViewPager的使用如下:
render(){
return (
<ViewPagerAndroid
style={styles.viewPager}
initialPage={0}>
<View style={styles.pageStyle}>
<Text>First page</Text>
</View>
<View style={styles.pageStyle}>
<Text>Second page</Text>
</View>
</ViewPagerAndroid>
);
}
其中,在ViewPager中罗列了很多的View,这种写法直接写死了ViewPager中的内容,而且不利于复用。(以下的实践均未考虑过性能,由于只是入门级的思考与实践,以熟悉ES6语法和RN的封装为目的,进行Demo的编写)因此可以参考Android的结构,对AndroidViewPager进行封装,对外提供的Component只需要Adapter一个属性,具体的数据源在Adapter中存放,同时Adapter提供了具体子View的render()方法。
该Demo的样式为:
下面是具体的代码结构:
//最小的DataBean 由图片的路径和图片的名称组成
export default class DataBean extends Object {
string_path = '';
string_name = '';
}
import DataBean from "./DataBean";
//ViewPager中具体的ModelBean,其中包含了N个DataBean
export default class ViewPagerBean {
dataBeans=[];
initData(paths,names) {
for (let i=0;i<paths.length;i++) {
let dataBean = new DataBean();
dataBean.string_name = names[i];
dataBean.string_path = paths[i];
this.dataBeans.push(dataBean);
}
}
getDataBeans() {
return this.dataBeans;
}
}
import ViewPagerBean from "./ViewPagerBean";
import React, {Component} from 'react';
import {
View,
Image, Text,
} from 'react-native';
import ChildViewComponent from "../ChildViewComponent";
var viewPagerBeans = [];
//类似于Android中的ViewPagerAdapter,提供数据源和具体View的实现
export default class ViewPagerAdapter {
//初始化数据(或可以改成set方法,用来初始化数据源)
initData() {
let path = 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg';
let viewPagerBean = new ViewPagerBean();
viewPagerBean.initData([path, path], ['111', '111']);
viewPagerBeans.push(viewPagerBean);
let viewPagerBean1 = new ViewPagerBean();
viewPagerBean1.initData([path, path], ['222', '222']);
viewPagerBeans.push(viewPagerBean1);
let viewPagerBean2 = new ViewPagerBean();
viewPagerBean2.initData([path, path], ['333', '333']);
viewPagerBeans.push(viewPagerBean2);
let viewPagerBean3 = new ViewPagerBean();
viewPagerBean3.initData([path, path], ['444', '444']);
viewPagerBeans.push(viewPagerBean3);
}
//获取数据源
getDataBeans() {
return viewPagerBeans;
}
//根据具体的viewPager的position来进行view的提供
initViewPage(position) {
let viewPagerBean = viewPagerBeans[position];
let dataBean = viewPagerBean.getDataBeans();
console.log(dataBean);
let path = dataBean[0].string_path;
let name = dataBean[0].string_name;
return(
<View style={{flex:1,flexDirection:'row',justifyContent:'space-around'}} key={'viewpager' + position}>
<View>
<ChildViewComponent icon_uri={path} icon_name={name}/>
</View>
</View>
);
}
}
import React,{Component} from 'react';
import {
ViewPagerAndroid,
View,
Text,
} from 'react-native';
import ChildViewComponent from "./ChildViewComponent";
import * as ToastAndroid from "react-native/Libraries/Components/ToastAndroid/ToastAndroid.android";
//对ViewPagerAndroid进行的一次封装,对外提供GomeViewPager
export default class GomeViewPager extends Component {
position = 0;
_onPageSelected(event) {
ToastAndroid.show('当前 --- 第' + event.nativeEvent.position + '页', ToastAndroid.LONG);
this.position = event.nativeEvent.position;
}
_generateViews(viewPagerAdapter) {
let views = [];
for (let i=0;i<viewPagerAdapter.getDataBeans().length;i++) {
views.push(viewPagerAdapter.initViewPage(i));
}
return(
views
);
}
render() {
return(
<ViewPagerAndroid initialPage={0} style={{height: 200}} onPageSelected={(event) => this._onPageSelected(event)}>
{this._generateViews(this.props.viewPagerAdapter)}
</ViewPagerAndroid>
)
}
}
使用:
render() {
//new出一个adapter,然后初始化数据
let adapter = new ViewPagerAdapter();
adapter.initData();
return (
<View>
<ViewPagerAndroid initialPage={0} style={{height: 200}}>
<View style={{backgroundColor: 'red'}}>
<Text>我是第一页</Text>
</View>
<View style={{backgroundColor: 'yellow'}}>
<Text>我是第二页</Text>
</View>
</ViewPagerAndroid>
<GomeViewPager viewPagerAdapter={adapter}/>
</View>
);
}