Handling hardware back button in Ionic3 Vs Ionic4

懵懂的女人 提交于 2019-12-17 15:44:47

问题


Please find the below code for the Android hardware back button action in ionic3. As Ionic4 uses angular routing for navigation how the pop event will take place for the back button? If we want to pop to the last page we can use the following code this.navCtrl.goBack('/products');. But how we can use it for the android hardware back button action in ionic4?

Ionic3 hardware back button action

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");
            }
        }
    }
});

回答1:


Update: This was fixed in dfac9dc


Related: ionic4 replacement for registerBackButtonAction


This is tracked on GitHub, in the Iconic Forum and Twitter
Until there is an official fix, you can use the workaround below.


Using platform.backButton.subscribe (see here) platform.backButton.subscribeWithPriority(0, ...) to let ionic handle closing all the modals/alerts/... , the code ionic uses when its own back button is pressed and the new router-controller together we get something like this:

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");
    }
  });
}



回答2:


Try This: 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();
                    }
                }
            });
        });
    }
}

it's work for me, in ionic v4 beta




回答3:


For Ionic4, I tried this method and it is working fine for me.

When the view is entering I am subscribing it variable and when it leaves then unsubscribe. So that the exiting app on the back button will execute for that particular page only.

constructor(private platform: Platform){}
backButtonSubscription;
ionViewWillEnter() {
  this.backButtonSubscription = this.platform.backButton.subscribe(async () => {
  navigator['app'].exitApp();
  });
 }
}
ionViewDidLeave() {
 this.backButtonSubscription.unsubscribe();
}



回答4:


this is how i do in my app (developed using ionic4 works in android apps). so when the user click back on android phone, app exits.

sample code:

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();
  }
}

source : here



来源:https://stackoverflow.com/questions/51700879/handling-hardware-back-button-in-ionic3-vs-ionic4

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!