36

Android OS について学習しようとしていますが、Google I/O 2014 アプリを読んでいるときにWindowInsets. 誰かがそれらが何であるかを説明できれば、それは大きな助けになるでしょう. ありがとうございました。

4

3 に答える 3

82

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その子に渡されるときに呼び出されることに注意してください。FrameLayoutLinearLayoutしない、する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

その他のリソース:

于 2016-08-13T06:26:47.087 に答える
12

Android システムは、上部のステータス バーや下部のナビゲーション バーなど、画面の一部を使用して独自のコンテンツをレンダリングします。たとえば、アプリが下部のバーの後ろにレンダリングする場合は、下部のバーによって消費される領域を考慮する必要があります。そうしないと、アプリの UI がシステム UI と競合し、次のような結果が得られます¹:

ボトムバーの後ろに隠れている FAB ボタンの例

上の画像では、ボタンが下のバーと交差しないように、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 インセット タイプについて説明しています。

参照:


¹画像はGesture Navigation: going edge-to-edge (I)の記事から取得したものです。

²画像は、ジェスチャー ナビゲーション: ジェスチャーの競合の処理 (III)の記事から取得したものです。

于 2020-10-31T19:01:47.157 に答える
11

ここで WindowInsetsのすべてを学ぶことができます。WindowInsetsアプリケーションが使用できるウィンドウ上の領域を提供します。それ自体はあまり役に立ちません。View.onApplyWindowInsets真の目的は、オーバーライドまたは実装するときに発生しますView.OnApplyWindowInsetsListener。ここでそれらについて読むことができます: View.onApplyWindowInsetsおよびView.OnApplyWindowInsetsListener

カスタムの方法でビューにウィンドウ インセットを適用するためのリスナー。

ビューのウィンドウ インセットの処理方法にカスタム ポリシーを適用する場合、アプリはこのインターフェイスの実装を選択できます。OnApplyWindowInsetsListener が設定されている場合、View 自体の onApplyWindowInsets メソッドの代わりに、その onApplyWindowInsets メソッドが呼び出されます。リスナーは、必要に応じてパラメータ ビューの onApplyWindowInsets メソッドを呼び出して、ビューの通常の動作を独自の一部として適用できます。

つまり、これをオーバーライドすると、ビューで使用できるウィンドウの領域を制御できます。

于 2015-11-09T13:06:26.177 に答える