React Native 指定頁面實體傳回監聽
在Android機上,實體傳回是一個很常用的功能,本文将講解如何在react-native中對實體傳回進行處理,分别為首頁面連續兩次退出程式,普通頁面回到上一頁,指定頁面特殊處理。
一. 首頁面連續兩次退出程式及普通頁面傳回上一頁
- 首先我們要先在頁面上增加實體監聽,建議在主Navigator頁面增加,就是有如下空間的頁面裡。
<Navigator
style={styles.navigator}
configureScene={this.configureScene}
renderScene={this.renderScene}
initialRoute={{
id: 'Splash',
}} />
- 添加監聽
componentWillMount() {
if (Platform.OS === 'android') {
BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
}
}
handleBackButton() {
for (let i = this.handlers.length - ; i >= ; i--) {
if (this.handlers[i]()) {
return true;
}
}//指定頁面特殊處理
const routers = this.navigator.getCurrentRoutes();
if (routers.length > ) {
this.navigator.pop();
return true;
}
let now = new Date().getTime();
if (now - lastClickTime < ) {
//2.5秒内點選後退鍵兩次推出應用程式
return false;//控制權交給原生
}
lastClickTime = now;
ToastAndroid.show('再按一次退出一個',ToastAndroid.SHORT);
return true;
}
對了 這裡的this.handleBackButton要在頁面初始化的地方bind一下
this.handleBackButton = this.handleBackButton.bind(this);
-
基本完成
經過上面的處理,我們可以基本的實作對實體傳回的監聽,如果不是初始頁面(即routes裡還有其他頁面),則把頁面彈出,回到上一頁,否則在2,5秒内按兩次實體傳回就可以退出程式。
二. 特殊頁面的傳回監聽
1. childContextTypes
通過添加 childContextTypes 和 getChildContext() 到 context 的提 供者,React 自動向下傳遞資料然後在元件樹中的任意元件(也就是說任意子元件,在本次中将是一個函數 )都能通過定義 contextTypes 通路 context 中的資料
大概是這麼個意思,建議要弄明白的可以自己查一下
2. 首頁面處理
在初始化(constructor(props) )的地方建立一個數組,将用來存儲那些特定頁面的監聽函數
3. 目前頁面新增兩個函數
用來添加及删除特殊頁面的實體監聽,并将它們提供給向下的元件樹
addBackButtonListener(listener) {
this.handlers.push(listener);
}
removeBackButtonListener(listener) {
this.handlers = this.handlers.filter((handler) => handler !== listener);
}
static childContextTypes = {
addBackButtonListener: React.PropTypes.func,
removeBackButtonListener: React.PropTypes.func
}
getChildContext() {
return {
addBackButtonListener: this.addBackButtonListener,
removeBackButtonListener: this.removeBackButtonListener,
};
}
4. 子元件(特殊頁面)特殊處理
(1) 擷取父元件的函數
static contextTypes = {
removeBackButtonListener: React.PropTypes.func.isRequired,
addBackButtonListener: React.PropTypes.func.isRequired,
};
(2) 新增新的監聽函數
handleBackButton() {
let {navigator} = this.props;
let routers = navigator.getCurrentRoutes();
if (routers[routers.length - ].id === "XXXXXXXX") {
//為了保險起見 因為有時候監聽不會立刻被解除安裝,防止在其他頁面觸發該監聽
this.existAlert();//特殊處理
return true;
} else {
return false;
}
}
(3) 将函數添加到監聽隊列中(仍要記得bind)
componentDidMount() {
this.context.addBackButtonListener(this.handleBackButton);
}
componentWillUnmount() {
this.context.removeBackButtonListener(this.handleBackButton);
}
(4)功能完成了。
三.實作的原理
通過childContextTypes,首頁面将增删實體監聽的函數提供給了子頁面。在子頁面中,如果需要特殊處理實體傳回監聽,可以調用該方法,把目前頁面的特殊處理方法添加到首頁面的監聽隊列中。當按下實體傳回,會先檢視特殊監聽隊列,是否有特殊處理,有的話特殊處理,沒有的話,将按普通的實體傳回進行處理
代碼
下面是我的github上的源碼,裡面特殊處理的頁面為滑出的抽屜
還有一些練手小東西,有興趣的可以看一下
源碼