fitSystemWindows到底能做什么?


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;
}

随着新的Material设计的出现,新的类大量使用了此标志,这就是混淆的地方。在许多资料中fitsSystemWindows都提到将标记设置为将视图放置在系统栏后面。看这里

ViewCompat.javafor中的文档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);
    }
}

而且我们在new CoordinatorLayoutAppBarLayout

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

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


1
这似乎是一个错误,我已经发布了错误报告对Android的问题跟踪
蒂姆·雷伊


感谢您的链接,非常有用。尽管如此,它仍然确认那里存在不一致之处。在链接的页面中,它说一些新的小部件(例如CoordinatorLayout)使用该标记来推断它们是否应在状态栏后面绘制。FrameLayout举例来说,情况并非如此。
引脚

2
这是一个很好的问题,并且可以很好地研究Android源代码。我特别感谢您确定新的MD类如何以不同的方式处理fitsSystemWindows。...我真想找出答案!
coolDude18年

Answers:


19

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

在大多数情况下,您的应用无需在状态栏或导航栏下绘制,但是如果您这样做,则需要:确保交互元素(如按钮)没有隐藏在其下方。这就是android:fitsSystemWindows =“ true”属性的默认行为:它设置了View的padding以确保内容不会覆盖系统窗口。

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


1
好吧,我明白
MJ工作室

6

它没有在系统栏后面绘制,而是在系统栏后面延伸以用相同的颜色对其进行着色,但是如果有意义的话,将其包含的视图填充在状态栏中

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.