【问题标题】:Handling hardware back button in Ionic3 Vs Ionic4在 Ionic 3 与 Ionic 4 中处理硬件后退按钮
【发布时间】:2019-01-13 00:21:31
【问题描述】:

请在ionic3 中找到以下 Android 硬件返回按钮操作的代码。由于Ionic4 使用角度路由进行导航,后退按钮将如何发生弹出事件?如果我们想跳到最后一页,我们可以使用下面的代码this.navCtrl.goBack('/products');。 但是我们如何将它用于ionic4中的android硬件后退按钮操作呢?

Ionic3 硬件后退按钮操作

this.platform.registerBackButtonAction(() => {
    let activePortal = this.ionicApp._loadingPortal.getActive() ||
        this.ionicApp._modalPortal.getActive() ||
        this.ionicApp._toastPortal.getActive() ||
        this.ionicApp._overlayPortal.getActive();
    if (activePortal) {
        activePortal.dismiss();
    } else {
        if (this.nav.canGoBack()) {
            ***this.nav.pop();***
        } else {
            if (this.nav.getActive().name === 'LoginPage') {
                this.platform.exitApp();
            } else {
                this.generic.showAlert("Exit", "Do you want to exit the app?", this.onYesHandler, this.onNoHandler, "backPress");
            }
        }
    }
});

【问题讨论】:

  • 我们的解决方法有效,您可以试试吗?

标签: ionic3 ionic4


【解决方案1】:

更新:此问题已在 v4.0.0-beta.8 (dfac9dc)

中修复

Related: ionic4 replacement for registerBackButtonAction


这是在 GitHubIconic ForumTwitter 上跟踪的
在正式修复之前,您可以使用以下解决方法。


使用 platform.backButton.subscribe(参见here platform.backButton.subscribeWithPriority(0, ...) 让 ionic 处理关闭所有模式/警报/... ,当its own back button is pressed 和新的router-controller 一起使用时,离子使用的代码是这样的:

import { ViewChild } from '@angular/core';
import { IonRouterOutlet, Platform } from '@ionic/angular';
import { Router } from '@angular/router';

//...

/* get a reference to the used IonRouterOutlet 
assuming this code is placed in the component
that hosts the main router outlet, probably app.components */
@ViewChild(IonRouterOutlet) routerOutlet: IonRouterOutlet;

constructor(
  ...
  /* if this is inside a page that was loaded into the router outlet,
  like the start screen of your app, you can get a reference to the 
  router outlet like this:
  @Optional() private routerOutlet: IonRouterOutlet, */
  private router: Router,
  private platform: Platform
  ...
) {
  this.platform.backButton.subscribeWithPriority(0, () => {
    if (this.routerOutlet && this.routerOutlet.canGoBack()) {
      this.routerOutlet.pop();
    } else if (this.router.url === '/LoginPage') {
      this.platform.exitApp(); 

      // or if that doesn't work, try
      navigator['app'].exitApp();
    } else {
      this.generic.showAlert("Exit", "Do you want to exit the app?", this.onYesHandler, this.onNoHandler, "backPress");
    }
  });
}

【讨论】:

  • 嗨@Fabian,感谢您的更新,但我有一些问题。首先,当我调试 ionBackButton 指令时,canGoBack 函数总是返回 false,那么我该如何启用它呢?我的第二个问题,如何以编程方式处理后退按钮?,因为我想在返回之前处理一些情况。谢谢,
  • @Fabian,您的解决方案部分有效。应用程序即使从根页面也不退出
  • @AnandRaj 尝试将其替换为 navigator['app'].exitApp();
  • 看看这里,stackoverflow.com/questions/27137119/… 老实说我从来没有质疑过它的有效性,因为它适用于我测试过的所有设备。
  • 老实说 navigator['app'].exitApp() 也不起作用。
【解决方案2】:

试试这个: app.comonent.ts

import { Component, ViewChildren, QueryList } from '@angular/core';
import { Platform, ModalController, ActionSheetController, PopoverController, IonRouterOutlet, MenuController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { Router } from '@angular/router';
import { Toast } from '@ionic-native/toast/ngx';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html'
})
export class AppComponent {

    // set up hardware back button event.
    lastTimeBackPress = 0;
    timePeriodToExit = 2000;

    @ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;

    constructor(
        private platform: Platform,
        private splashScreen: SplashScreen,
        private statusBar: StatusBar,
        public modalCtrl: ModalController,
        private menu: MenuController,
        private actionSheetCtrl: ActionSheetController,
        private popoverCtrl: PopoverController,
        private router: Router,
        private toast: Toast) {

        // Initialize app
        this.initializeApp();

        // Initialize BackButton Eevent.
        this.backButtonEvent();
    }

    // active hardware back button
    backButtonEvent() {
        this.platform.backButton.subscribe(async () => {
            // close action sheet
            try {
                const element = await this.actionSheetCtrl.getTop();
                if (element) {
                    element.dismiss();
                    return;
                }
            } catch (error) {
            }

            // close popover
            try {
                const element = await this.popoverCtrl.getTop();
                if (element) {
                    element.dismiss();
                    return;
                }
            } catch (error) {
            }

            // close modal
            try {
                const element = await this.modalCtrl.getTop();
                if (element) {
                    element.dismiss();
                    return;
                }
            } catch (error) {
                console.log(error);

            }

            // close side menua
            try {
                const element = await this.menu.getOpen();
                if (element) {
                    this.menu.close();
                    return;

                }

            } catch (error) {

            }

            this.routerOutlets.forEach((outlet: IonRouterOutlet) => {
                if (outlet && outlet.canGoBack()) {
                    outlet.pop();

                } else if (this.router.url === '/home') {
                    if (new Date().getTime() - this.lastTimeBackPress < this.timePeriodToExit) {
                        // this.platform.exitApp(); // Exit from app
                        navigator['app'].exitApp(); // work in ionic 4

                    } else {
                        this.toast.show(
                            `Press back again to exit App.`,
                            '2000',
                            'center')
                            .subscribe(toast => {
                                // console.log(JSON.stringify(toast));
                            });
                        this.lastTimeBackPress = new Date().getTime();
                    }
                }
            });
        });
    }
}

这对我有用,在 ionic v4 beta 中

【讨论】:

  • 这仅适用于部署到应用商店的混合应用吗?所以它不适用于 PWA?因为我无法让它工作
  • @MD.Riyaz 您可以使用backButton.subscribeWithPriority(0, ...) 让 ionic 为您关闭所有模态/...。
  • outlet.canGoBack() 总是返回 false... 即使使用 navCtrl.navigateForward('...') 导航
  • @Miquel 我有一个基于角度路由器的导航的解决方法,只有一个出口:我在我的应用程序组件构造函数中保存了根页面setTimeout(() =&gt; this.rootPage = this.router.url) 的 url,然后将当前位置与此 url 进行比较看看我是否回到了第一方if (this.router.url == this.rootPage) { this.exit(); } else { this.location.back(); }
  • @MD.Riyaz this.menu.getOpen() 将在菜单被禁用的根页面上返回 undefined
【解决方案3】:

这是我在 Ionic 5 项目上的工作代码。 使用 Cordova/PhoneGap

import {Component} from '@angular/core';
import {ToastService} from './_services/toast.service';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  constructor(private toastCtrl: ToastService) {
    this.backButton();
  }
  backButton() {
      const that = this;
      let lastTimeBackPress = 0;
      const timePeriodToExit = 2000;
      function onBackKeyDown(e) {
          e.preventDefault();
          e.stopPropagation();
          if (new Date().getTime() - lastTimeBackPress < timePeriodToExit) {
              navigator.app.exitApp();
          } else {
              that.presentToast();
              lastTimeBackPress = new Date().getTime();
          }
      }
      document.addEventListener('backbutton', onBackKeyDown, false);
  }
  presentToast() {
    const toast = this.toastCtrl.create({
      message: "Press again to exit",
      duration: 3000,
      position: "middle"
    });
  toast.present();
  }
}

或看到这个:- https://thaaimozhikalvi.com/2020/05/28/ionic-5-double-tab-back-button-to-exit-using-cordova-phonegap/

【讨论】:

  • 谢谢,这在 Ionic 5 中运行良好。但答案下方提供的链接已损坏。
【解决方案4】:

这就是我在我的应用程序中所做的(使用 ionic4 开发的适用于 android 应用程序)。所以当用户点击安卓手机时,应用程序退出。

示例代码:

import { Component, AfterViewInit, OnDestroy } from '@angular/core';
import { Platform } from '@ionic/angular';
@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent implements AfterViewInit, OnDestroy {

  constructor(private platform: Platform) { }
  backButtonSubscription;
  ngAfterViewInit() {
    this.backButtonSubscription = this.platform.backButton.subscribe(() => {
      // add logic here if you want to ask for a popup before exiting
      navigator['app'].exitApp();
    });
  }

  ngOnDestroy() {
    this.backButtonSubscription.unsubscribe();
  }
}

来源:here

【讨论】:

【解决方案5】:

使用cordova事件“后退按钮”

document.addEventListener("backbutton", youFunction, false);

我使用 ionic4/vue 并且效果很好

【讨论】:

    【解决方案6】:

    在 Ionic 4 中自定义 Android 后退按钮 ...每个页面都返回。

    第一步:import { Platform, NavController } from '@ionic/angular';

    第二步:constructor(public navCtrl: NavController){}

    第 3 步:

     private async onBack() {
        this.navCtrl.navigateBack('/project-details');
      }
    

    第 4 步:

     this.platform.backButton.subscribe(()=>{
            this.onBack();
          });
    

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 2017-06-20
      • 1970-01-01
      相关资源
      最近更新 更多