runoops.com

ionic 硬件后退按钮

硬件后退按钮可在大多数Android设备上找到。在本机应用程序中,它可用于关闭模态、导航到上一个视图、退出应用程序等。默认情况下,在 Ionic 中,当按下后退按钮时,当前视图将从导航堆栈中弹出,并显示上一个视图。如果导航堆栈中不存在以前的视图,则不会发生任何操作。本章将展示如何自定义硬件后退按钮的行为。

硬件后退按钮是指 Android 设备上的物理后退按钮,不应与浏览器后退按钮或离子后退按钮混淆。本章中的信息仅适用于安卓设备。

Capacitor 和 Cordova 中的硬件后退按钮

必须在 Capacitor 应用中安装 @capacitor/app 包才能使用硬件后退按钮。

在 Capacitor 或 Cordova 应用程序中运行时,当用户按下硬件后退按钮时,Ionic Framework 将发出 ionBackButton 事件。

侦听 ionBackButton 事件时,可以注册要触发的处理程序。此处理程序可以执行退出应用或打开确认对话框等操作。必须为每个处理程序分配一个优先级。默认情况下,每次按硬件后退按钮仅触发一个处理程序。优先级值用于确定应调用哪个回调。这很有用,因为如果打开了模式,则在按下硬件后退按钮时,你可能不希望模式关闭并且应用向后导航。一次只运行一个处理程序允许模式关闭,但仍需要再次按硬件后退按钮才能向后导航。

在某些情况下,您可能希望触发多个处理程序。每个处理程序回调都作为参数传入一个函数,该参数可用于告诉框架调用下一个处理程序。

浏览器的硬件后退按钮

在移动浏览器中或作为 PWA 运行应用时,硬件后退按钮自定义将受到限制。这是因为Capacitor 和 Cordova 公开了普通 Web 浏览器中未公开的其他功能。例如,在移动浏览器中运行应用时,通过硬件后退按钮关闭叠加层和菜单是当前不支持的功能。这些是已知的限制,目前没有直接的解决方案。

对于完整的硬件后退按钮支持,我们建议使用Capacitor 和 Cordova 。

在浏览器中或作为 PWA 运行应用时,不会发出 ionBackButton 事件。

基本用法

document.addEventListener('ionBackButton', (ev) => {
  ev.detail.register(10, () => {
    console.log('Handler was called!');
  });
});
import { Platform } from '@ionic/angular';

...

constructor(private platform: Platform) {
  this.platform.backButton.subscribeWithPriority(10, () => {
    console.log('Handler was called!');
  });
}
document.addEventListener('ionBackButton', (ev) => {
  ev.detail.register(10, () => {
    console.log('Handler was called!');
  });
});
import { useBackButton } from '@ionic/vue';

...

export default {
  setup() {
    useBackButton(10, () => {
      console.log('Handler was called!');
    });
  }
}

在此示例中,我们将注册一个处理程序,以便在按下硬件后退按钮时调用。我们已将优先级设置为 10,并且我们没有向框架指示我们希望调用下一个处理程序。因此,将不会调用优先级小于 10 的任何处理程序。优先级大于 10 的处理程序将首先被调用。

如果存在具有相同优先级值的处理程序,则将调用上次注册的处理程序。有关详细信息,请参阅具有相同优先级的处理程序。

调用多个处理程序

每个硬件后退按钮回调都有一个processNextHandler 参数。调用此函数允许您继续调用硬件后退按钮处理程序。

document.addEventListener('ionBackButton', (ev) => {
  ev.detail.register(5, () => {
    console.log('Another handler was called!');
  });

  ev.detail.register(10, (processNextHandler) => {
    console.log('Handler was called!');

    processNextHandler();
  });
});
import { Platform } from '@ionic/angular';

...

constructor(private platform: Platform) {
  this.platform.backButton.subscribeWithPriority(5, () => {
    console.log('Another handler was called!');
  });

  this.platform.backButton.subscribeWithPriority(10, (processNextHandler) => {
    console.log('Handler was called!');

    processNextHandler();
  });
}
document.addEventListener('ionBackButton', (ev) => {
  ev.detail.register(5, () => {
    console.log('Another handler was called!');
  });

  ev.detail.register(10, (processNextHandler) => {
    console.log('Handler was called!');

    processNextHandler();
  });
});
import { useBackButton } from '@ionic/vue';

...

export default {
  setup() {
    useBackButton(5, () => {
      console.log('Another handler was called!');
    });

    useBackButton(10, (processNextHandler) => {
      console.log('Handler was called!');

      processNextHandler();
    });
  }
}

具有相同优先级的处理

有多个具有相同优先级值的处理,例如:

JavaScript:

document.addEventListener('ionBackButton', (ev) => {
  // Handler A
  ev.detail.register(10, (processNextHandler) => {
    console.log('Handler A was called!');

    processNextHandler();
  });

  // Handler B
  ev.detail.register(10, (processNextHandler) => {
    console.log('Handler B was called!');

    processNextHandler();
  });
});

此处,Handler B 优先于Handler A 被调用。

退出 App

退出App 可以通过使用ionBackButton事件与Capacitor/Cordova提供的方法相结合来实现:

import { BackButtonEvent } from '@ionic/core';
import { App } from '@capacitor/app';

...

const routerEl = document.querySelector('ion-router');
document.addEventListener('ionBackButton', (ev: BackButtonEvent) => {
  ev.detail.register(-1, () => {
    const path = window.location.pathname;
    if (path === routerEl.root) {
      App.exitApp();
    }
  });
});
import { Optional } from '@angular/core';
import { IonRouterOutlet, Platform } from '@ionic/angular';
import { App } from '@capacitor/app';

...

constructor(
  private platform: Platform,
  @Optional() private routerOutlet?: IonRouterOutlet
) {
  this.platform.backButton.subscribeWithPriority(-1, () => {
    if (!this.routerOutlet.canGoBack()) {
      App.exitApp();
    }
  });
}
import { useIonRouter } from '@ionic/react';
import { App } from '@capacitor/app';

...

const ionRouter = useIonRouter();
document.addEventListener('ionBackButton', (ev) => {
  ev.detail.register(-1, () => {
    if (!ionRouter.canGoBack()) {
      App.exitApp();
    }
  });
});
import { useBackButton, useIonRouter } from '@ionic/vue';
import { App } from '@capacitor/app';

...

export default {
  setup() {
    const ionRouter = useIonRouter();
    useBackButton(-1, () => {
      if (!ionRouter.canGoBack()) {
        App.exitApp();
      }
    });
  }
}

建议在退出应用程序之前检查用户是否在根页面上。开发人员可以在 Ionic Angular 的 IonRouterOutlet 上使用 canGoBack 方法,在 Ionic React 和 Ionic Vue 中使用 IonRouter 方法。

内部框架处理

Ionic Framework 使用的所有内部硬件后退按钮事件处理程序,Propagates 列记录该特定处理程序是否告诉 Ionic Framework 调用下一个后退按钮处理程序:

处理程序优先级PropagatesDescription
Overlays100No应用于overlay 组件 ion-action-sheetion-alertion-loadingion-modalion-popover, and ion-picker.
Menu99No应用于 ion-menu.
Navigation0Yes应用于 routing navigation (例如 Angular Routing).

Captcha Code

0 笔记

分享笔记

Inline Feedbacks
View all notes