一部のデバイスでは、ディスプレイ カットアウトはディスプレイ サーフェスまで広がる領域です。デバイスの前面に重要なセンサー用のスペースを確保しながら、エッジ ツー エッジのエクスペリエンスを実現します。
Android は、Android 9(API レベル 28)以降を搭載しているデバイスでディスプレイ カットアウトをサポートします。ただし、デバイス メーカーは、Android 8.1 以前を搭載しているデバイスでディスプレイ カットアウトをサポートすることもできます。
このドキュメントでは、カットアウト領域(カットアウトを含むディスプレイ サーフェス上の端から端までの長方形)の操作方法など、カットアウトのあるデバイスのサポートを実装する方法について説明します。
アプリでのカットアウト領域の処理方法を選択する
コンテンツがカットアウト領域に重ならないようにするには、通常、コンテンツがステータスバーやナビゲーション バーと重ならないようにすれば十分です。カットアウト領域にレンダリングする場合は、WindowInsetsCompat.getDisplayCutout()
を使用して、各カットアウトの安全なインセットと境界ボックスを含む DisplayCutout
オブジェクトを取得します。これらの API を使用すると、コンテンツがカットアウトと重なっているかどうかを確認できるため、必要に応じて配置を変更できます。
また、コンテンツがカットアウト領域の背後に配置されるかどうかも指定できます。layoutInDisplayCutoutMode
ウィンドウ レイアウト属性は、カットアウト領域にコンテンツを描画する方法を制御します。layoutInDisplayCutoutMode
は次のいずれかの値に設定できます。
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: コンテンツを常にカットアウト領域に拡張できます。これは、Android 15 以降を搭載したデバイスのデフォルト モードです。LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: 縦向きと横向きの両方で、コンテンツがカットアウト領域にレンダリングされます。フローティング ウィンドウには使用しないでください。LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: コンテンツがカットアウト領域にレンダリングされることはありません。
カットアウト モードは、プログラムで設定することも、アクティビティでスタイルを設定して設定することもできます。以下の例では、LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
属性をアクティビティに適用するスタイルを定義しています。
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
以降のセクションでは、さまざまなカットアウト モードについて詳しく説明します。
デフォルトの動作
特別なフラグが設定されていない縦向きのデフォルトでは、カットアウトがあるデバイスのステータスバーはカットアウトと同じ高さにサイズ変更され、コンテンツはその下の領域に表示されます。横向きまたは全画面モードでは、アプリ ウィンドウがレターボックス表示され、コンテンツがカットアウト領域に表示されません。
短い辺のカットアウト領域にコンテンツをレンダリングする
動画、写真、地図、ゲームなどのコンテンツでは、カットアウト領域でレンダリングすると、より没入感のあるエッジ ツー エッジのエクスペリエンスを提供できます。LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
を使用すると、コンテンツは縦向きと横向きの両方で、システムバーが非表示か表示されているかにかかわらず、ディスプレイの短辺のカットアウト領域にまで広がります。このモードを使用する場合は、重要なコンテンツがカットアウト領域と重ならないようにしてください。
次の図は、縦向きのデバイスの LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
の例です。
次の図は、横向きデバイスの LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
の例です。
このモードでは、ウィンドウがシステムバーを非表示にしているかどうかにかかわらず、縦向きと横向きの両方で、ディスプレイの短辺のカットアウトの下にウィンドウが拡張されます。
隅のカットアウトは短辺にあるとみなされます。
コンテンツをディスプレイ カットアウト領域にレンダリングしない
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
では、ウィンドウがカットアウト領域と重なることはありません。
縦向きの LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
の例を次に示します。
横向きモードの LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
の例を次に示します。
ディスプレイ カットアウトのサポートに関するベスト プラクティス
ディスプレイ カットアウトを使用する場合は、次の点を考慮してください。
- UI の重要な要素の配置に注意してください。カットアウト領域によって重要なテキスト、コントロール、その他の情報が隠れないようにしてください。
- きめ細かい認識が必要なインタラクティブ要素をカットアウト領域に配置または拡張しないでください。カットアウト領域では、タップの感度が低くなる場合があります。
可能であれば、
WindowInsetsCompat
を使用してステータスバーの高さを取得し、コンテンツに適用する適切なパディングを決定します。ステータスバーの高さをハードコードしないようにしてください。ハードコードすると、コンテンツが重なったり、切り取られたりすることがあります。View.getLocationInWindow()
を使用して、アプリが使用しているウィンドウ領域の量を確認します。アプリがウィンドウ全体を使用しているとは想定せず、View.getLocationOnScreen()
も使用しません。アプリを没入モードに切り替える、または没入モードから切り替える必要がある場合は、
shortEdges
またはnever
カットアウト モードを使用します。デフォルトのカットアウト動作では、システムバーが存在する場合はアプリのコンテンツがカットアウト領域にレンダリングされますが、没入モードでは表示されない場合があります。これにより、次の例に示すように、遷移中にコンテンツが上下に移動します。没入モードでは、ウィンドウ座標と画面座標を使用する際は注意が必要です。アプリでレターボックス表示を行うと、画面全体が使用されないためです。レターボックス表示のため、画面の原点からの座標はウィンドウの原点からの座標とは異なります。必要に応じて、
getLocationOnScreen()
を使用して画面座標をビュー座標に変換できます。次の図は、コンテンツがレターボックス表示されるときの座標の違いを示しています。MotionEvent
を処理する際は、MotionEvent.getX()
とMotionEvent.getY()
を使用して、同様の座標の問題が発生しないようにしてください。MotionEvent.getRawX()
やMotionEvent.getRawY()
は使用しないでください。
コンテンツのレンダリング方法をテストする
アプリの画面とエクスペリエンスのすべてをテストします。可能であれば、さまざまな種類のカットアウトを持つデバイスでテストします。カットアウトのあるデバイスがない場合は、次の手順に沿って、Android 9 以降を搭載したデバイスまたはエミュレータで一般的なカットアウト構成をシミュレートできます。
- [開発者向けオプション] を有効にします。
- [開発者向けオプション] 画面で [描画] セクションまで下にスクロールし、[カットアウトでディスプレイをシミュレート] を選択します。
カットアウトのタイプを選択します。