我努力理解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;
}


随着新的Material设计的出现,新的类大量使用了此标志,这就是混淆的地方。在许多来源中,提到fitsSystemWindows作为设置以将视图放置在系统栏后面的标志。请参见here

ViewCompat.javasetFitsSystemWindows中的文档说:


设置此视图是否应考虑系统屏幕装饰
例如状态栏并插入其内容;也就是说,控制是否
{@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);
    }
}


我们在新的CoordinatorLayoutAppBarLayout中看到了相同的模式。

这不是以与fitsSystemWindows文档完全相反的方式工作吗?在最后一种情况下,这意味着在系统栏后面拖拉。

但是,如果您希望FrameLayout在状态栏后面绘制自身,则将fitsSystemWindows设置为true并不能解决问题,因为默认实现会执行最初记录的内容。您必须重写它,并添加与其他提到的类相同的标志。我想念什么吗?

最佳答案

系统窗口是系统绘制屏幕的部分
非交互式(对于状态栏)或交互式
(对于导航栏)内容。

大多数情况下,您的应用无需在状态栏或
导航栏,但如果这样做:您需要确保交互式
元素(如按钮)并未隐藏在其下方。那就是
android:fitsSystemWindows =“ true”属性的默认行为
给您:它设置视图的填充以确保内容
不要覆盖系统窗口。


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

09-05 21:58