Android OS について学習しようとしていますが、Google I/O 2014 アプリを読んでいるときにWindowInsets
. 誰かがそれらが何であるかを説明できれば、それは大きな助けになるでしょう. ありがとうございました。
3 に答える
WindowInsets
ウィンドウに適用されるシステム ビュー (ステータス バー、ナビゲーション バーなど) のインセット (またはサイズ) です。
具体的な例で理解するのは簡単でしょう。このシナリオをイメージしてください:
WindowInsets
ここで、 background に適用したくありません。ImageView
その場合、ImageView
ステータス バーの高さによってパディングされるためです。
しかし、インセットを に適用する必要はありません。Toolbar
そうしないと、Toolbar
ステータス バーの途中に描画されるからです。
WindowInsets
ビューは、次のように xml で適用することを宣言します。
android:fitsSystemWindows="true"
この例では、 をルート レイアウトに適用できません。これWindowInsets
は、ルート レイアウトが を消費WindowInsets
し、ImageView
がパディングされるためです。
代わりに、ViewCompat.setOnApplyWindowInsetsListener
インセットをツールバーに適用するために使用できます。
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin =
insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
このコールバックは、Toolbar
のルート レイアウトがWindowsInsets
その子に渡されるときに呼び出されることに注意してください。FrameLayout
、LinearLayout
しない、するDrawerLayout
、のようなレイアウトCoordinatorLayout
。
たとえば、レイアウトをサブクラス化してFrameLayout
オーバーライドできonApplyWindowInsets
ます。
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++)
getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets
return insets;
}
この件に関する Ian Lake によるmediumの素敵なブログ投稿と、 Chris Banes による「マスター ウィンドウ フィッターになる」プレゼンテーションがあります。
また、Mediumで sに関する詳細な記事を作成しましたWindowInset
。
その他のリソース:
Android システムは、上部のステータス バーや下部のナビゲーション バーなど、画面の一部を使用して独自のコンテンツをレンダリングします。たとえば、アプリが下部のバーの後ろにレンダリングする場合は、下部のバーによって消費される領域を考慮する必要があります。そうしないと、アプリの UI がシステム UI と競合し、次のような結果が得られます¹:
上の画像では、ボタンが下のバーと交差しないように、FAB ボタンに余分な下マージンを追加する必要があります。WindowInsets APIを使用すると、システム UI が消費する下部インセットなどの情報を取得できます。fitsSystemWindows
同様の目的を果たす属性に出くわすことがよくあります。属性の詳細と、の代わりにいつ使用する必要があるかについては、この回答WindowInsets
を参照してください。こちらの素晴らしい記事もご覧ください: Gesture Navigation: handling visual overloads (II)。待って、ジェスチャー ナビゲーションとは何ですか?
視覚的なオーバーラップだけが直面する問題ではありません。Android 10 (API 29) 以降、新しいジェスチャー ナビゲーションモードが追加されました。ユーザーは、上の画像のようなボタン バーの代わりに、ジェスチャーを使用してアプリ間を移動することを選択できるようになりました。ユーザーがよりモダンな UX を利用できるように、アプリをナビゲーション バーの背後に描画することを強くお勧めします。しかし、それに加えて、新しいインセット タイプ、ジェスチャー インセットが導入されました。ジェスチャー ナビゲーションモードが選択されている場合、アプリのジェスチャーがシステムのジェスチャーと競合する可能性があることが判明しました。たとえば、次の画像² を見てみましょう。
ご覧のとおり、シーク バーが下端に近すぎて、システムのクイック スイッチ ジェスチャと競合しています。システム ジェスチャが優先されるため、シーク バーが使用できなくなります。この例と他の一般的なシナリオは、ジェスチャー ナビゲーション: ジェスチャーの競合の処理 (III)の記事で詳しく説明されています。
上記の記事は、Android チームで働くChris Banesによって書かれたGesture Navigationシリーズの一部です。テーマをより深く理解したい場合は、シリーズ全体を読むことをお勧めします。別の記事Animating your keyboard (part 1)も役立つかもしれません。この記事では、WindowInsets API の進行中の変更と、新しい IME インセット タイプについて説明しています。
参照:
- ジェスチャーナビシリーズ
- 正確には、fitsSystemWindows は何をしますか?
- キーボードのアニメーション化 (パート 1)
- WindowInsets — レイアウトに対するリスナー
- なぜシステム Windows に適合したいのですか?
- ウィンドウフィッターの達人になる (droidcon London 2017)
¹画像はGesture Navigation: going edge-to-edge (I)の記事から取得したものです。
²画像は、ジェスチャー ナビゲーション: ジェスチャーの競合の処理 (III)の記事から取得したものです。
ここで WindowInsetsのすべてを学ぶことができます。WindowInsets
アプリケーションが使用できるウィンドウ上の領域を提供します。それ自体はあまり役に立ちません。View.onApplyWindowInsets
真の目的は、オーバーライドまたは実装するときに発生しますView.OnApplyWindowInsetsListener
。ここでそれらについて読むことができます: View.onApplyWindowInsetsおよびView.OnApplyWindowInsetsListener。
カスタムの方法でビューにウィンドウ インセットを適用するためのリスナー。
ビューのウィンドウ インセットの処理方法にカスタム ポリシーを適用する場合、アプリはこのインターフェイスの実装を選択できます。OnApplyWindowInsetsListener が設定されている場合、View 自体の onApplyWindowInsets メソッドの代わりに、その onApplyWindowInsets メソッドが呼び出されます。リスナーは、必要に応じてパラメータ ビューの onApplyWindowInsets メソッドを呼び出して、ビューの通常の動作を独自の一部として適用できます。
つまり、これをオーバーライドすると、ビューで使用できるウィンドウの領域を制御できます。