参考的方案
我的处理方法是基于小军617 给出的方案,请参考
ionic2实战-完美处理安卓硬件返回按钮
//www.greatytc.com/p/6aa5a8318092?mType=Group
遇到的问题
app.component.ts中的rootPage设置为login页面,登录成功后设置根页面为tabs页面,调用的方法如下:
this.navCtrl.setRoot('TabsPage',{}, {
keyboardClose: true,
isNavRoot: true
});
进入到登录页面后,android返回键失灵。
解决方法
先看下小军处理方案中的一段主要代码:
let activeVC = this.nav.getActive();
let tabs = activeVC.instance.tabs;
let activeNav = tabs.getSelected();
return activeNav.canGoBack() ? activeNav.pop() : this.showExit()
通过this.nav.getActive()获取到当前激活的ViewController,然后处理返回逻辑。那么我为什么会遇到返回键失灵的问题呢?经过调试发现,当调用setRoot()方法后,此处的nav对象已经发生了变化,获取不到当前激活的ViewController。
问题的关键是如何获取到当前激活的ViewController,而这个我们可以通过当前的RootNavController获取。所以修改后的代码如下:
this.platform.registerBackButtonAction(() => {
if (this.keyboard.isOpen()) {//如果键盘开启则隐藏键盘
this.keyboard.close();
return;
}
let rootNav = this.appCtrl.getRootNavs()[0];
//如果想点击返回按钮隐藏toast或loading或Overlay就把下面加上
let ionicApp = rootNav._app._appRoot;
let activePortal = ionicApp._toastPortal.getActive() || ionicApp._loadingPortal.getActive()
|| ionicApp._overlayPortal.getActive() || ionicApp._modalPortal.getActive();
if (activePortal) {
let actInstance = activePortal.instance;
if (actInstance instanceof LoginPage) {
return this.nativeSv.alertExitApp('确认退出软件?');
} else if (actInstance instanceof ContactSelectPage) {
return actInstance.closePage();
}
setTimeout(() => {//延迟200毫秒
activePortal && activePortal.dismiss();
}, 200);
return;
}
let tabs = rootNav.getActive().instance.tabs;
if (tabs) {
let activeNav = tabs.getSelected();
return activeNav.canGoBack() ? activeNav.pop() : this.nativeSv.minimize();//this.showExit()
} else {
return this.nativeSv.alertExitApp('确认退出软件?');
}
}, 100);
}
设置root页面的代码也要修改一下:
constructor(public appCtrl: App) { }
doLogin() {
//登录成功后,跳转到tabs页面
let rootNav = this.appCtrl.getRootNavs()[0];
rootNav.setRoot(MainPage, {}, {
keyboardClose: true,
isNavRoot: true
}).then(() => {
this.storage.set("has-logined", true);
});
//登录失效后,已modal方式打开login页面
//登录成功后,需要把modal关闭
let activePortal = rootNav._app._appRoot._modalPortal.getActive();
if (activePortal && activePortal.instance instanceof LoginPage) {
this.viewCtrl.dismiss();
}
}