硬件返回按钮
硬件返回按钮位于大多数 Android 设备上。在原生应用程序中,它可以用于关闭模态框,导航到上一个视图,退出应用程序等等。在 Ionic 中,默认情况下,当按下返回按钮时,当前视图将从导航堆栈中弹出,并将显示上一个视图。如果导航堆栈中不存在上一个视图,则不会发生任何操作。本指南将演示如何自定义硬件返回按钮的行为。
硬件返回按钮是指 Android 设备上的物理返回按钮,不应与浏览器返回按钮或ion-back-button
混淆。本指南中的信息仅适用于 Android 设备。
概述
Ionic 框架在用户在支持的环境中按下硬件返回按钮时会发出ionBackButton
事件。
在监听ionBackButton
事件时,您可以注册一个要触发的处理程序。此处理程序可以执行诸如退出应用程序或打开确认对话框之类的操作。每个处理程序必须分配一个优先级。默认情况下,每次按下硬件返回按钮时只触发一个处理程序。优先级值用于确定应该调用哪个回调。这很有用,因为如果您打开了一个模态框,您可能不希望模态框关闭并且应用程序在按下硬件返回按钮时向后导航。一次只运行一个处理程序允许模态框关闭,但仍然需要再次按下硬件返回按钮才能向后导航。
在某些情况下,您可能希望触发多个处理程序。每个处理程序回调都传递一个函数作为参数,该函数可用于告诉 Ionic 调用下一个处理程序。
支持
下表显示了硬件返回按钮支持在不同环境中的差异。
环境 | 状态 |
---|---|
Capacitor | 仅在安装了@capacitor/app 包时受支持。 |
Cordova | 支持 |
浏览器 | 仅在experimentalCloseWatcher 为true 且平台支持 Close Watcher API 时受支持。 |
PWA | 仅在experimentalCloseWatcher 为true 且平台支持 Close Watcher API 时受支持。 |
浏览器或 PWA 中的硬件返回按钮
Ionic 通过在 IonicConfig 中设置experimentalCloseWatcher: true
,对在浏览器或 PWA 中处理硬件返回按钮提供了实验性支持。启用此功能后,Ionic 将使用Close Watcher API,通过ionBackButton
事件传递任何关闭请求。这包括按下硬件返回按钮以导航或按下 Escape 键以关闭模态框。
Chrome 从Chrome 120开始支持 Close Watcher。
为了获得完整的硬件返回按钮支持,我们建议使用 Capacitor 或 Cordova。
如果 Close Watcher 不受支持或experimentalCloseWatcher
为false
,则在浏览器中或作为 PWA 运行应用程序时不会发出ionBackButton
事件。
基本用法
- JavaScript
- Angular
- Angular(独立)
- React
- Vue
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!');
});
}
import { Platform } from '@ionic/angular/standalone';
...
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
参数。调用此函数允许您继续调用硬件返回按钮处理程序。
- JavaScript
- Angular
- Angular(独立)
- React
- Vue
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();
});
}
import { Platform } from '@ionic/angular/standalone';
...
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();
});
}
}
此示例演示如何告诉 Ionic 框架您希望触发下一个处理程序。所有回调都提供processNextHandler
函数作为参数。调用它将导致触发下一个处理程序(如果存在)。
具有相同优先级的处理程序
在内部,Ionic 框架使用类似于优先级队列的东西来管理硬件返回按钮处理程序。具有最大优先级值的处理程序将首先被调用。如果有多个处理程序具有相同的优先级值,则添加到此队列的具有相同优先级的最后一个处理程序将是第一个被调用的处理程序。
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();
});
});
在上面的示例中,处理程序 A 和 B 的优先级均为 10。由于处理程序 B 是最后注册的,因此 Ionic 框架将在调用处理程序 A 之前调用处理程序 B。
退出应用程序
在某些情况下,可能希望在按下硬件返回按钮时退出应用程序。这可以通过使用ionBackButton
事件以及 Capacitor/Cordova 提供的方法来实现。
- JavaScript
- Angular
- Angular(独立)
- React
- Vue
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 { Optional } from '@angular/core';
import { IonRouterOutlet, Platform } from '@ionic/angular/standalone';
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
和 Ionic React 和 Ionic Vue 中的IonRouter
上的canGoBack
方法。
内部框架处理程序
下表列出了 Ionic 框架使用的所有内部硬件返回按钮事件处理程序。传播
列表示该特定处理程序是否告诉 Ionic 框架调用下一个返回按钮处理程序。
处理程序 | 优先级 | 传播 | 描述 |
---|---|---|---|
覆盖层 | 100 | 否 | 适用于覆盖层组件ion-action-sheet 、ion-alert 、ion-loading 、ion-modal 、ion-popover 和ion-picker 。 |
菜单 | 99 | 否 | 适用于ion-menu 。 |
导航 | 0 | 是 | 适用于路由导航(即 Angular 路由)。 |