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