着脱式キーボードをサポートすることで、大画面デバイスでのユーザーの生産性を最大限に高めることができます。Android では、キーボードがデバイスに着脱されるたびに構成の変更がトリガーされるため、UI の状態が失われる可能性があります。アプリは、状態を保存して復元し、アクティビティの再作成をシステムに処理させることも、キーボード構成の変更に対するアクティビティの再作成を制限することもできます。
いずれの場合も、キーボードに関連するすべてのデータは Configuration
オブジェクトに保存されます。構成
オブジェクトのkeyboard フィールドと keyboardHidden フィールドには、キーボードの種類とその可用性に関する情報が含まれています。
ベスト プラクティス
大画面向けに最適化されたアプリは、ソフトウェア キーボードやハードウェア キーボードから、スタイラス、マウス、トラックパッド、その他の周辺機器まで、あらゆる種類の入力デバイスをサポートしています。
外部キーボードのサポートには構成の変更が伴いますが、これは次の 2 つの方法で管理できます。
- 実行中のアクティビティをシステムに再作成させ、アプリの状態の管理はユーザーが行います。
- 構成の変更を自分で管理します(アクティビティは再作成されません)。
- キーボード関連の構成値をすべて宣言します
- 構成変更ハンドラを作成します
生産性向上アプリでは、テキスト入力やその他の入力のために UI を細かく制御する必要があることが多いため、構成の変更を自分で処理する方法が役立ちます。
特別なケースでは、ハードウェア キーボードが着脱されたときにアプリのレイアウトを変更することがあります。たとえば、ツールや編集ウィンドウのためのスペースを増やす場合などです。
Jetpack Compose では、キーボード構成の変更に次の 2 つの方法で対応できます。
- リアクティブ UI:
LocalConfiguration.currentを使用して、コンポーザブルで現在の構成状態を直接読み取ります。キーボードが着脱されると、UI は自動的に再コンポーズされ、新しい状態に適応します。 - 副作用コールバック: ライフサイクル対応の
DisposableEffectを使用して、ホスト アクティビティに構成変更リスナーを登録します。これにより、アクティビティを再作成したり、ダミーのビュー要素をインスタンス化したりすることなく、UI 以外のイベント(ロギングや分析など)をトリガーできます。
材料
android:configChanges: アプリ マニフェストの<activity>要素の属性。アプリが管理する構成の変更をシステムに通知します。LocalConfiguration: 現在の デバイスConfigurationを公開するコンポーザブル ローカル プロバイダ。DisposableEffect: コンポーザブルがコンポジションに入るときにコードブロックを実行し、コンポジションから出るときにクリーンアップする Compose 副作用 API。
手順
configChanges 属性を宣言し、キーボード関連の値を追加してアクティビティの再作成を防ぎます。次に、LocalConfiguration.current を使用してコンポーザブル レイアウトを動的に適応させるか、DisposableEffect を使用して構成リスナーを登録します。
1. configChanges 属性を宣言する
アプリ マニフェストの <activity> 要素を更新して、すでに管理されている構成
変更のリストに
keyboard|keyboardHidden 値を追加します。
<activity
…
android:configChanges="...|keyboard|keyboardHidden">
2. キーボード構成の変更に対応する
Jetpack Compose で構成の変更を処理するには、UI を更新するか、副作用コールバックを実行するかに応じて、次のいずれかのオプションを使用します。
オプション A: リアクティブ UI(推奨)
キーボードの種類を
LocalConfiguration.currentから直接読み取ります。ハードウェア キーボードが着脱されると、この値が変更され、Compose が UI を自動的に再コンポーズします。val configuration = LocalConfiguration.current val isPhysicalKeyboardAttached = configuration.keyboard == Configuration.KEYBOARD_QWERTY if (isPhysicalKeyboardAttached) { // Render layout optimized for physical keyboard } else { // Render default layout }
オプション B: 副作用リスナー
構成が変更されたときに副作用(ロギング、ローカル データベースの更新、分析のトリガーなど)を実行する必要がある場合は、
DisposableEffectを使用して、ホストComponentActivityに構成変更リスナーを登録します。val context = LocalActivity.current DisposableEffect(context) { val activity = context as? ComponentActivity val listener = Consumer<Configuration> { newConfig -> val hasKeyboard = newConfig.keyboard == Configuration.KEYBOARD_QWERTY // Trigger non-UI actions, analytics, etc. } activity?.addOnConfigurationChangedListener(listener) onDispose { activity?.removeOnConfigurationChangedListener(listener) } }
結果
アプリは、実行中のアクティビティを再作成することなく、外部キーボードの着脱に対応するようになります。
参考情報
キーボードの着脱などの構成変更時にアプリの UI の状態を保存する方法については、UI の状態を保存するをご覧ください。