breaking the habit
阿新 • • 發佈:2019-01-24
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 - 1; i >= 0; i--) {
if (this.handlers[i]()) {
return true;
}
}//指定頁面特殊處理
const routers = this.navigator.getCurrentRoutes();
if (routers.length > 1) {
this.navigator.pop();
return true;
}
let now = new Date().getTime();
if (now - lastClickTime < 2500) {
//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) )的地方建立一個數組,將用來儲存那些特定頁面的監聽函式
this.handlers = ([]:Array<() => boolean>);
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 - 1].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上的原始碼,裡面特殊處理的頁面為滑出的抽屜
還有一些練手小東西,有興趣的可以看一下
原始碼