我正在努力理解 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
被认为是设置为将视图放置在系统栏后面的标志。见 给你。
setFitsSystemWindows
的 ViewCompat.java
文档说:
设置此视图是否应考虑系统屏幕修饰 如状态栏并插入其内容; < strong > 即控制是否 {@link View # fitSystemWindows (Rect)}的默认实现将为 有关更多细节,请参见该方法 .
根据这个,fitsSystemWindows
只是意味着函数 fitsSystemWindows()
将被执行?新的材质类似乎只是用来在状态栏下绘图。如果我们看看 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);
}
}
我们在新的 CoordinatorLayout
或 AppBarLayout
中看到了相同的模式。
这是否与 fitsSystemWindows
的文档以完全相反的方式工作? 在最后一种情况下,它的意思是 躲在系统栏后面。
但是,如果您希望 FrameLayout
在状态栏后面绘制自己,那么将 fitsSystemWindows
设置为 true 并不能达到预期效果,因为默认实现会执行最初记录的操作。您必须重写它,并添加与其他提到的类相同的标志。我错过了什么吗?