fitsSystemWindowsは正確には何をしますか?


126

fitsSystemWindowsさまざまなことを行うビューに依存するという概念を理解するのに苦労しています。公式ドキュメントによると、それは

ステータスバーなどのシステムウィンドウに基づいてビューのレイアウトを調整するブール内部属性。trueの場合、このビューのパディングを調整して、システムウィンドウ用のスペース残します

これでView.javaクラスを確認すると、に設定するtrueと、ウィンドウのインセット(ステータスバー、ナビゲーションバー...)がビューのパディングに適用され、上記のドキュメントに従って機能することがわかります。これはコードの関連部分です:

private boolean fitSystemWindowsInt(Rect insets) {
    if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
        mUserPaddingStart = UNDEFINED_PADDING;
        mUserPaddingEnd = UNDEFINED_PADDING;
        Rect localInsets = sThreadLocal.get();
        if (localInsets == null) {
            localInsets = new Rect();
            sThreadLocal.set(localInsets);
        }
        boolean res = computeFitSystemWindows(insets, localInsets);
        mUserPaddingLeftInitial = localInsets.left;
        mUserPaddingRightInitial = localInsets.right;
        internalSetPadding(localInsets.left, localInsets.top,
                localInsets.right, localInsets.bottom);
        return res;
    }
    return false;
}

新しいマテリアルデザインでは、このフラグを多用する新しいクラスがあり、混乱が生じます。多くのソースでfitsSystemWindowsは、システムバーの背後にビューを配置するために設定するフラグとして言及されています。こちらをご覧ください

ドキュメントViewCompat.javaのためには、setFitsSystemWindowsこう述べています。

このビューがステータスバーなどのシステム画面の装飾を考慮し、そのコンテンツを挿入するかどうかを設定します。つまり、{@ link View#fitSystemWindows(Rect)}のデフォルト実装を実行するかどうかを制御します。詳細については、そのメソッドを参照してください

これによると、fitsSystemWindows単に関数fitsSystemWindows()が実行されることを意味しますか?新しいMaterialクラスは、ステータスバーの下の描画にこれを使用するようです。DrawerLayout.javaのコードを見ると、次のことがわかります。

if (ViewCompat.getFitsSystemWindows(this)) {
        IMPL.configureApplyInsets(this);
        mStatusBarBackground = IMPL.getDefaultStatusBarBackground(context);
    }

...

public static void configureApplyInsets(View drawerLayout) {
    if (drawerLayout instanceof DrawerLayoutImpl) {
        drawerLayout.setOnApplyWindowInsetsListener(new InsetsListener());
        drawerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
}

また、新しいCoordinatorLayoutorにも同じパターンが表示されAppBarLayoutます。

これは、ドキュメントとまったく逆の方法で機能しませんfitsSystemWindowsか?最後のケースでは、システムバーの後ろにドローします。

ただし、FrameLayoutステータスバーの背後にそれ自体を描画したい場合はfitsSystemWindows、デフォルトの実装が最初に文書化されていることを実行するため、true に設定してもうまくいきません。それをオーバーライドして、他の言及されたクラスと同じフラグを追加する必要があります。何か不足していますか?


1
これはバグのようです。Androidの問題トラッカーにバグレポートを投稿しました
Tim Rae

1
ここを確認してください:medium.com/google-developers/…
ファティS.

リンクをありがとう、とても便利です。それでも、そこには矛盾があることが確認されます。リンクされたページで、などの新しいウィジェットのいくつかはCoordinatorLayout、ステータスバーの背後にペイントする必要があるかどうかを推測するためにそのフラグを使用すると書かれています。FrameLayoutたとえば、はそうではありません。
ピン

2
これはすばらしい質問で、Androidのソースコードを調べるのに非常に優れた作業でした。新しいMDクラスがfitsSystemWindowsをどのように処理するかを識別したことを特に感謝します。
coolDude 2018

回答:


19

システムウィンドウは、システムが非インタラクティブ(ステータスバーの場合)またはインタラクティブ(ナビゲーションバーの場合)のコンテンツを描画している画面の一部です。

ほとんどの場合、アプリはステータスバーやナビゲーションバーの下に描画する必要はありませんが、描画する場合は、インタラクティブ要素(ボタンなど)が下に隠れていないことを確認する必要があります。これがandroid:fitsSystemWindows =“ true”属性のデフォルトの動作で得られるものです。ビューのパディングを設定して、コンテンツがシステムウィンドウに重ならないようにします。

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec


1
わかりました
MJスタジオ

6

システムバーの後ろには描画されず、バーの後ろに伸びて、同じ色で色付けされますが、含まれているビューは、状況に応じてステータスバーの内側に埋め込まれます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.