硬體返回按鈕
硬體返回按鈕在大多數 Android 裝置上都有。在原生應用程式中,它可以用於關閉模組、導覽至上一個視圖、結束應用程式等等。在 Ionic 中,預設情況下,當按下返回按鈕時,目前視圖會從導覽堆疊中彈出,並顯示上一個視圖。如果導覽堆疊中沒有上一個視圖,則不會發生任何事。本指南將說明如何自訂硬體返回按鈕的行為。
硬體返回按鈕指的是 Android 裝置上的實體返回按鈕,不應與瀏覽器返回按鈕或 ion-back-button
混淆。本指南中的資訊僅適用於 Android 裝置。
總覽
當使用者在支援的環境中按下硬體返回按鈕時,Ionic Framework 會發出 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
事件。這包括按下硬體返回按鈕來導覽或按下 Esc 鍵來關閉模組。
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 Framework 指示您想要觸發下一個處理程式。所有回呼都會以 processNextHandler
函數作為參數提供。呼叫此函數將導致觸發下一個處理程式 (如果存在)。
具有相同優先順序的處理程式
在內部,Ionic Framework 使用類似於優先順序佇列的東西來管理硬體返回按鈕處理程式。優先順序值最大的處理程式會先被呼叫。如果存在多個具有相同優先順序值的處理程式,則會呼叫*最後*新增至此佇列的相同優先順序的處理程式。
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 Framework 會在呼叫處理程式 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 Framework 使用的所有內部硬體返回按鈕事件處理程式。Propagates
欄位指出該特定處理程式是否告訴 Ionic Framework 呼叫下一個返回按鈕處理程式。
處理程式 | 優先順序 | 傳播 | 描述 |
---|---|---|---|
覆蓋層 | 100 | 否 | 適用於覆蓋層元件 ion-action-sheet 、ion-alert 、ion-loading 、ion-modal 、ion-popover 和 ion-picker 。 |
選單 | 99 | 否 | 適用於 ion-menu 。 |
導覽 | 0 | 是 | 適用於路由導覽 (即 Angular 路由)。 |