ハードウェアの戻るボタン
ハードウェアの戻るボタンは、ほとんどの Android デバイスにあります。ネイティブアプリケーションでは、これを使って、モデルを閉じたり、前のビューに移動したり、アプリを終了したりすることができる。既定値では、 戻るボタンを押すと、現在のビューがナビゲーションスタックからポップされ、前のビューが表示されます。ナビゲーションスタックに前のビューが存在しない場合は、何も起こりません。このガイドでは、ハードウェアの戻るボタンの動作をカスタマイズする方法について説明します。
ハードウェアの 「戻る」 ボタンとは Android デバイスの物理的な 「戻る」 ボタンのことであり、ブラウザの 「戻る」 ボタンや ion-back-button
ボタンと混同しないでください。このガイドの情報は、Android デバイスにのみ適用されます。
概要
Ionic Framework は、サポートされている環境でユーザーがハードウェアの戻るボタンを押すと、ionBackButton
イベントを発行します。
ionBackButton
イベントを監視して、起動するハンドラを登録できます。このハンドラは、アプリケーションの終了や確認ダイアログのオープンなどのアクションを実行できます。各ハンドラには優先順位を割り当てる必要があります。既定では、ハードウェアの戻るボタンを押すごとに 1 つのハンドラだけが起動されます。優先順位の値は、どのコールバックを呼び出すかを決定するために使用されます。これが便利なのは、モーダルを開いている場合、ハードウェアの戻るボタンを押したときにモーダルが閉じられたり、アプリが後方に移動したりしないようにしたいからです。一度に 1 つのハンドラだけを実行すると、モーダルを閉じることができますが、戻るにはハードウェアの戻るボタンをもう一度押す必要があります。
複数のハンドラを起動したい場合があります。各ハンドラのコールバックは、フレームワークに次のハンドラを呼び出すように指示するために使用できるパラメーターとして関数を渡します。
Support
The table below shows how hardware back button support varies by environment.
Environment | Status |
---|---|
Capacitor | Supported only when the @capacitor/app package is installed. |
Cordova | Supported |
Browser | Supported only when experimentalCloseWatcher is true and the platform supports the Close Watcher API. |
PWA | Supported only when experimentalCloseWatcher is true and the platform supports the Close Watcher API. |
Hardware Back Button in a Browser or a PWA
Ionic has experimental support for handling the hardware back button in a browser or a PWA by setting experimentalCloseWatcher: true
in the IonicConfig. When this feature is enabled, Ionic will use the Close Watcher API to pass any close requests through the ionBackButton
event. This includes pressing the hardware back button to navigate or the Escape key to dismiss a modal.
Chrome has support for Close Watcher starting in Chrome 120.
ハードウェアバックボタンを完全にサポートするには、Capacitor または Cordova の使用をお勧めします。
The ionBackButton
event will not be emitted when running an app in a browser or as a PWA if Close Watcher is unsupported or experimentalCloseWatcher
is false
.
Basic Usage
- JavaScript
- Angular
- Angular (Standalone)
- 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 より大きいハンドラが最初に呼び出されます。
同じ優先順位値を持つハンドラが存在する場合は、最後に登録されたハンドラが呼び出されます。詳細は、 Handlers with the Same Priorities を参照してください。
複数ハンドラの呼び出し
各ハードウェアバックボタンコールバックには、 processNextHandler
パラメータがあります。この関数を呼び出すと、ハードウェアバックボタンハンドラの呼び出しを続行できます。
- JavaScript
- Angular
- Angular (Standalone)
- 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 はハードウェアのバックボタンハンドラを管理するためにプライオリティキューに似たものを使用します。優先順位の値が最大のハンドラが最初に呼び出されます。同じ優先順位のハンドラが複数存在する場合、このキューに追加された同じ優先順位の last handler が、最初に呼び出されるハンドラになります。
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 を呼び出します。
アプリの終了
場合によっては、ハードウェアの戻るボタンを押したときにアプリケーションを終了することをお勧めします。これは、Capacitor/Cordova が提供するメソッドと組み合わせた ionBackButton
イベントを使用することで実現できます。
- JavaScript
- Angular
- Angular (Standalone)
- 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
でcanGoBack
、 Ionic React および Ionic Vue の IonRouter
で canGoBack
メソッドを使用できます。
内部フレームワークハンドラ
次の表は、Ionic Framework が使用するすべての内部ハードウェアバックボタンイベントハンドラの一覧です。 Propagates
列は、その特定のハンドラが Ionic Framework に次の戻るボタンハンドラを呼び出すように指示するかどうかを示します。
Handler | Priority | Propagates | Description |
---|---|---|---|
Overlays | 100 | No | Applies to overlay components ion-action-sheet , ion-alert , ion-loading , ion-modal , ion-popover , and ion-picker . |
Menu | 99 | No | Applies to ion-menu . |
Navigation | 0 | Yes | Applies to routing navigation (i.e. Angular Routing). |