在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>
);
}