ハードウェア戻るボタン
ハードウェア戻るボタンは、ほとんどのAndroidデバイスにあります。ネイティブアプリケーションでは、モーダルの閉じ、前のビューへの移動、アプリの終了など、様々な用途に使用できます。Ionicではデフォルトで、戻るボタンを押すと、現在のビューがナビゲーションスタックからポップされ、前のビューが表示されます。ナビゲーションスタックに前のビューが存在しない場合、何も起こりません。このガイドでは、ハードウェア戻るボタンの動作をカスタマイズする方法を示します。
ハードウェア戻るボタンとは、Androidデバイスの物理的な戻るボタンを指し、ブラウザの戻るボタンやion-back-button
とは混同しないでください。このガイドの情報は、Androidデバイスのみに適用されます。
概要
Ionic Frameworkは、サポートされている環境でユーザーがハードウェア戻るボタンを押すと、ionBackButton
イベントを発行します。
ionBackButton
イベントをリッスンすると、実行されるハンドラーを登録できます。このハンドラーは、アプリの終了や確認ダイアログの表示などのアクションを実行できます。各ハンドラーには優先順位を割り当てる必要があります。デフォルトでは、ハードウェア戻るボタンの1回の押しにつき、1つのハンドラーのみが実行されます。優先順位値を使用して、どのコールバックを呼び出すかを決定します。これは、モーダルが開いている場合、ハードウェア戻るボタンを押したときにモーダルが閉じられるだけでなく、アプリが後方に移動することも避けたい場合に役立ちます。一度に1つのハンドラーしか実行しないことで、モーダルを閉じることができる一方で、後方に移動するにはハードウェア戻るボタンをもう一度押す必要があります。
複数のハンドラーを実行したい場合もあります。各ハンドラーコールバックは、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 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を呼び出します。
アプリの終了
いくつかのシナリオでは、ハードウェア戻るボタンを押したときにアプリを終了することが望ましい場合があります。これは、Capacitor/Cordovaが提供するメソッドと組み合わせたionBackButton
イベントを使用して実現できます。
- 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が使用するすべての内部ハードウェア戻るボタンイベントハンドラーをリストしています。「伝播」列は、その特定のハンドラーがIonic Frameworkに次の戻るボタンハンドラーを呼び出すように指示するかどうかを示しています。
ハンドラー | 優先順位 | 伝播 | 説明 |
---|---|---|---|
オーバーレイ | 100 | いいえ | オーバーレイコンポーネントion-action-sheet 、ion-alert 、ion-loading 、ion-modal 、ion-popover 、ion-picker に適用されます。 |
メニュー | 99 | いいえ | ion-menu に適用されます。 |
ナビゲーション | 0 | はい | ルーティングナビゲーション(例:Angularルーティング)に適用されます。 |