在我們開發Android的時候,ViewPage這個控制元件的使用頻率還是很高的,最簡單的就是製作引導頁,應用程式的主介面等,在ReactNative開發中實現該功能的元件是ViewPageAndroid,當你看到該元件是以Android結尾,你就明白該元件只對Android平臺有效,如果使用就要考慮適配iOS(目前學習到的ScrollView元件可以實現此效果,具體實現不在本篇文章介紹),今天就通過下面示例圖,介紹ViewPageAndroid的API以及使用。
基本用法
對於該元件內部可以巢狀View,每一個子View就相當於一個Page,每一個單獨的頁面顯示時它會拉伸填滿ViewPageAndroid。
return (
<ViewPagerAndroid style={{backgroundColor: `red`, flex: 1}}>
<View ><Text>1</Text></View>
<View><Text>2</Text></View>
<View><Text>3 </Text></View>
</ViewPagerAndroid>
)複製程式碼
在上面我麼給出了一個最簡單的展示ViewPagerAndroid的例子。我們在其內部加入了3個View,那麼也將顯示3頁,雖然View沒有設定樣式,如寬和高,,但是它會填充ViewPagerAndroid ,其實設定了寬和高也沒有用,不管設定寬高多少都是填滿ViewPageAndroid。如果不信你可以嘗試給第一個View新增樣式
style={{backgroundColor:`green`}}複製程式碼
設定後,發現第一頁顯示的背景是綠色。然後再給第一個View增加寬高屬性,都設定為100.如下
style={{backgroundColor:`green`,width:100,height:100}}複製程式碼
設定後發現第一頁的背景仍然全部是綠色,設定寬高屬性並沒有產生什麼作用。對於文章開始的示例圖展示,我們就是在VewPageAndroid元件中新增了5個子View,每一個View中有一個Image用於顯示圖片,和一個可點選的元件並且顯示點選次數。
const styles = StyleSheet.create({
button: {
backgroundColor: `#2196f3`,
borderRadius: 5,
marginHorizontal: 20,
marginTop: 10,
padding: 10,
},
buttonText: {
color: `white`,
},
container: {
flex: 1,
backgroundColor: `white`,
},
image: {
width: 300,
height: 200,
padding: 20,
},
viewPager: {
flex: 1,
},
});複製程式碼
由於ViewPageAndroid 5頁顯示的內容只是圖片,背景不一樣,其他都是通用的,我們就按如下建立
render() {
var pages = []
for (var i = 0; i < PAGES; i++) {
var pageStyle = {
backgroundColor: BGCOLOR[i % BGCOLOR.length],
alignItems: `center`,
padding: 20,
}
pages.push(
<View key={i} style={pageStyle} collapsable={false}>
<Image
style={styles.image}
resizeMode={Image.resizeMode.contain}
source={IMAGE_URIS[i % BGCOLOR.length]}
/>
<CustomCount/>
</View>
)
}
return (
<View style={styles.container}>
<ViewPagerAndroid
style={styles.viewPager}
ref={(viewPage) => {
this.viewPage = viewPage;
}}>
{pages}
</ViewPagerAndroid>
</View>
)
}複製程式碼
用到的圖片資源常量以及背景常量和頁數常量如下
const PAGES = 5;
const BGCOLOR = [`#fdc08e`, `#fff6b9`, `#99d1b7`, `#dde5fe`, `#f79273`];
const IMAGE_URIS = [
require(`./Thumbnails/cat.png`),
require(`./Thumbnails/monkey.png`),
require(`./Thumbnails/rabbit.png`),
require(`./Thumbnails/tiger.png`),
require(`./Thumbnails/duck.png`),
];複製程式碼
對於Image元件通過source指定要顯示的圖片,其它屬性使用可以參考之前的文章ReactNative Image元件詳解,CustomCount是定義的一個元件,
class CustomCount extends Component {
state = {
count: 1,
}
render() {
return (
<View>
<TouchableOpacity
activeOpacity={0.5}
onPress={() => this.setState({count: this.state.count + 1})}
style={{backgroundColor: `#38adff`, borderRadius: 5, marginTop: 20, padding: 10}}
>
<Text>我是可點選的 {this.state.count}</Text>
</TouchableOpacity>
</View>)
}
}複製程式碼
在定義的點選元件中設定一個狀態count,用於顯示點選次數。這樣我們就可以實現看到大致效果了。
設定初始化時顯示頁數
在預設的時候,總是顯示第一頁,很多時候,我們需要顯示指定的頁數,例如我們實現了一個日曆,有12頁(12個月),那我們點選開啟日曆時,要顯示當前月的資訊。如果當前是8月,那麼就要預設顯示第八頁,不需要再我們一頁一頁的翻到該頁,這時候就要使用initialPage 屬性,它可以指定第一個顯示的頁數,該值從0開始。如設定預設顯示第二頁,如下
initialPage={1}複製程式碼
keyboardDismissMode
如果我們使用了用於輸入的元件,就會彈出軟鍵盤,那麼在拖動翻頁時需要隱藏軟鍵盤,就需要使用此屬性,它有兩個值分別是none(預設值,拖拽不會讓鍵盤消失)和on-drag(當拖拽開始的時候會讓鍵盤消失)。如果我們設定滑動時隱藏軟鍵盤,如下
keyboardDismissMode="on-drag"複製程式碼
設定每相鄰頁之間的間距
在上面的展示圖中,我們看到每兩個相鄰頁顯示有10畫素的白色間距,這個效果是通過pageMargin屬性設定的,顏色對於間距顯示的的顏色,是ViewPagerAndroid中樣式設定的背景色,如果沒有設定,從它父檢視繼承。如我們設定間距10畫素
pageMargin={10}複製程式碼
scrollEnabled
該屬性是用來設定是否可以滾動支援,當設定true時表示可以滾動翻頁,預設值也是true,如果設定false的話,就表示不可滾動翻頁,如此此時想實現翻頁效果,那就需要使用setPage方法,稍後再介紹其使用。
顯示頁數指示器
在圖例中,我們看到有一個顯示當前頁數以及總頁數的指示器,要實現此功能,我們我們需要用到onPageSelected屬性函式,每當頁面切換完成後,該函式會呼叫,該函式有一個引數event,可以通過event.nativeEvent.position 獲取當前頁面的下標。
//增加屬性
onPageSelected={this._onPageSelected}
_onPageSelected = (event) => {
console.log(`_onPageSelected`)
this.setState({page: event.nativeEvent.position});
}複製程式碼
我們增加了一個狀態值page用於標示當前頁面的下標。然後在ViewPageAndroid下面新增元件Text,用於顯示當前頁面指示器。
<Text style={[style, {textAlign: `center`}]}>{this.state.page + 1}/{pages.length}</Text>複製程式碼
由於頁面下標從0開始,我們顯示時對其加1。通過上面我們實現了頁面指示器顯示。
很多時候,我們需要在需要在翻頁時實現一些動畫,例如翻頁時Tab的顏色變化動畫,在RN中,我們也可以實現效果,實現此效果時通過onPageScroll屬性函式,當我們拖動頁面時這個函式會一直回撥,該函式有一個引數,我們可以通過event.nativeEvent獲取我們需要的資料。
- position 從左數起第一個當前可見的頁面的下標。(經過測試這個資料的用處不大,切記這個position和onPageSelected攜帶的position值不一樣,不是當前頁面下標)
-
offset 一個在[0,1)(大於等於0,小於1)之間的範圍,代表當前頁面切換的狀態。值x表示現在”position”所表示的頁有(1 – x)的部分可見,而下一頁有x的部分可見。
看到了把offset 變化時0到1之間的數值,當向左滑動翻頁時(相當於下一頁)該值時0到1變化,向右滑動翻頁(相當於上一頁)是1到0變化。我們就可以通過該值進行一些類似微信那種透明讀,或者顏色深淺,等我們任何想要實現的動畫。onPageScrollStateChanged
該函式用於監測ViewPageAndroid的狀態,它有三個值
-
idle 空閒,意味著當前沒有互動。
- dragging 拖動中,意味著當前頁面正在被拖動。
- settling 處理中,意味著當前頁面發生過互動,且正在結束開頭或收尾的動畫。
我們增加一個狀態scrollState。然後如圖例一樣,將狀態顯示。
onPageScrollStateChanged={this._onPageScrollStateChanged}
_onPageScrollStateChanged = (state: ViewPagerScrollState) => {
console.log(`_onPageScrollStateChanged`)
this.setState({scrollState: state});
};複製程式碼
使用按鈕實現上下翻頁
在圖例中我們有上一頁和下一頁兩個按鈕。實現此功能可以通過ViewPagerAndroid的setPage方法
_onPress = (offset) => {
var goPage = (this.state.page + offset + PAGES) % PAGES
if (this.state.animationsAreEnabled) {
this.viewPage.setPage(goPage)
} else {
this.viewPage.setPageWithoutAnimation(goPage)
}
this.setState({page: goPage})
}複製程式碼
我將上一頁和下一頁點選事件統一處理了,當點選下一頁時引數傳1,當點選上一頁時引數傳-1。goPage 即使我們對將要跳轉的頁面下標做計算。如果當前是第一頁,再點選上一頁時將跳轉到最後一頁,計算到要跳轉的頁面下標後,呼叫setPage或者setPageWithoutAnimation都可以實現,區別通過名字頁顯而易見。當使用setPage時最後一頁和第一頁相互切換時會有個過度動畫。如果使用setPageWithoutAnimation就沒有動畫。
好了,ViewPageAndroid的相關介紹就到此為止了,想檢視全部原始碼,可前往GitHub,今天的這篇文章就到此結束了,若文中有錯誤的地方歡迎指出,共同進步,謝謝。Have a wonderful day.