Activity がすべてのインセットの処理を制御したら、Compose API を使用して、コンテンツが隠れていないこと、操作可能な要素がシステム UI と重なっていないことを確認できます。これらの API は、アプリのレイアウトをインセットの変更と同期させます。
パディングまたはサイズ修飾子を使用してインセットを処理する
たとえば、アプリ全体のコンテンツにインセットを適用する最も基本的な方法は次のとおりです。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
このスニペットは、アプリのコンテンツ全体に safeDrawing ウィンドウ インセットをパディングとして適用します。これにより、操作可能な要素がシステム UI と重なることはなくなりますが、アプリのコンテンツがシステム UI の背後に描画されてエッジ ツー エッジ効果を実現することもなくなります。ウィンドウ全体を最大限に活用するには、画面ごとまたはコンポーネントごとにインセットを適用する場所を微調整する必要があります。
これらのインセット タイプはすべて、API 21 にバックポートされた IME アニメーションで自動的にアニメーション化されます。これにより、これらのインセットを使用するすべてのレイアウトも、インセット値の変更に合わせて自動的にアニメーション化されます。
インセットを処理してコンポーザブル レイアウトを調整するには、次の 3 つの方法があります。
パディング修飾子
Modifier.windowInsetsPadding(windowInsets: WindowInsets) は、指定されたウィンドウ インセットをパディングとして適用し、Modifier.padding と同じように動作します。たとえば、Modifier.windowInsetsPadding(WindowInsets.safeDrawing) は、安全な描画インセットを 4 辺すべてにパディングとして適用します。
最も一般的なインセット タイプには、組み込みのユーティリティ メソッドもいくつかあります。Modifier.safeDrawingPadding() は、Modifier.windowInsetsPadding(WindowInsets.safeDrawing) と同等のメソッドです。他のインセット タイプにも同様の修飾子があります。
インセット サイズの修飾子
次の修飾子は、コンポーネントのサイズをインセットのサイズに設定することで、ウィンドウ インセットの量を適用します。
windowInsets の開始側を幅として適用します( |
|
windowInsets の end 側を幅として適用します( |
|
windowInsets の上辺を高さとして適用します( |
|
|
windowInsets の下辺を高さとして適用します( |
これらの修飾子は、インセットのスペースを占有する Spacer のサイズ設定に特に便利です。
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
インセットの消費
インセット パディング修飾子(windowInsetsPadding や safeDrawingPadding などのヘルパー)は、パディングとして適用されるインセットの一部を自動的に消費します。コンポジション ツリーを深く掘り下げると、ネストされたインセット パディング修飾子とインセット サイズ修飾子は、インセットの一部がすでに外側のインセット パディング修飾子によって使用されていることを認識し、インセットの同じ部分を複数回使用して余分なスペースが過剰になるのを防ぎます。
インセット サイズ修飾子は、インセットがすでに使用されている場合、インセットの同じ部分を複数回使用しないようにします。ただし、サイズを直接変更するため、インセット自体は消費しません。
そのため、パディング修飾子をネストすると、各コンポーザブルに適用されるパディングの量が自動的に変更されます。
前の LazyColumn の例を見ると、LazyColumn は imePadding 修飾子によってサイズ変更されています。LazyColumn 内の最後のアイテムは、システムバーの下部の高さになるようにサイズ設定されます。
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
IME が閉じている場合、IME に高さがないため、imePadding() 修飾子はパディングを適用しません。imePadding() 修飾子はパディングを適用しないため、インセットは使用されず、Spacer の高さはシステムバーの下側のサイズになります。
IME が開くと、IME インセットが IME のサイズに合わせてアニメーション化され、imePadding() 修飾子が下部のパディングの適用を開始して、IME が開くにつれて LazyColumn のサイズを変更します。imePadding() 修飾子が下部のパディングの適用を開始すると、その量のインセットの消費も開始します。そのため、システムバーの間隔の一部が imePadding() 修飾子によってすでに適用されているため、Spacer の高さが減少し始めます。imePadding() 修飾子がシステムバーよりも大きい下部パディング量を適用すると、Spacer の高さはゼロになります。
IME が閉じると、変更は逆方向に発生します。imePadding() がシステムバーの下辺よりも小さい値を適用し始めると、Spacer は高さ 0 から拡大し始め、IME が完全にアニメーションで消えると、Spacer はシステムバーの下辺の高さと一致します。
TextField を使用したエッジ ツー エッジの遅延列。この動作は、すべての windowInsetsPadding 修飾子間の通信によって実現されます。また、他の方法で影響を与えることもできます。
Modifier.consumeWindowInsets(insets: WindowInsets) も Modifier.windowInsetsPadding と同様にインセットを利用しますが、利用したインセットをパディングとして適用しません。これは、インセット サイズ修飾子と組み合わせて、特定の量のインセットがすでに消費されていることを兄弟に伝える場合に便利です。
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) は WindowInsets 引数を持つバージョンとよく似た動作をしますが、任意の PaddingValues を受け取って使用します。これは、インセット パディング修飾子以外のメカニズム(通常の Modifier.padding や固定高さのスペーサーなど)によってパディングやスペーシングが提供される場合に、子に通知するのに役立ちます。
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
消費なしで未加工のウィンドウ インセットが必要な場合は、WindowInsets 値を直接使用するか、WindowInsets.asPaddingValues() を使用して、消費の影響を受けないインセットの PaddingValues を返します。ただし、次の注意点があるため、可能な限りウィンドウ インセットのパディング修飾子とウィンドウ インセットのサイズ修飾子を使用することをおすすめします。
インセットと Jetpack Compose のフェーズ
Compose は、基盤となる AndroidX コア API を使用してインセットを更新およびアニメーション化します。この API は、インセットを管理する基盤となるプラットフォーム API を使用します。このプラットフォームの動作により、インセットは Jetpack Compose のフェーズと特別な関係を持ちます。
インセットの値は、コンポジション フェーズの後、レイアウト フェーズの前に更新されます。つまり、コンポジションでインセットの値を読み取る場合、通常は 1 フレーム遅れたインセットの値が使用されます。このページで説明する組み込みの修飾子は、レイアウト フェーズまでインセットの値の使用を遅らせるように構築されています。これにより、インセットの値は更新されたのと同じフレームで使用されます。