我正在尝试了解Android操作系统,当我阅读Google I / O 2014应用程序时,我遇到了WindowInsets
。如果有人能解释他们是什么,那将是一个很大的帮助。谢谢。
您可以了解有关WindowInsets here.的所有信息WindowInsets
为您提供了应用程序可用的窗口区域。它本身并没有多大用处。当你重写View.onApplyWindowInsets
或实现View.OnApplyWindowInsetsListener
时,这是真正的目的。你可以在这里阅读它们:View.onApplyWindowInsets和View.OnApplyWindowInsetsListener
侦听器以自定义方式在视图上应用窗口插入。
如果应用程序要将自定义策略应用于视图处理窗口插入的方式,则应用可以选择实现此接口。如果设置了OnApplyWindowInsetsListener,则将调用其onApplyWindowInsets方法,而不是View自己的onApplyWindowInsets方法。监听器可以选择调用参数View的onApplyWindowInsets方法,将View的正常行为作为其自身的一部分。
简而言之,覆盖它将允许您控制可用于View的窗口区域。
WindowInsets
是应用于窗口的系统视图(例如状态栏,导航栏)的插入(或大小)。
在具体的例子上很容易理解。想象这个场景:
现在,你不希望将WindowInsets
应用于背景ImageView
,因为在这种情况下,ImageView
将被状态栏高度填充。
但你确实希望将插图应用于Toolbar
,因为否则Toolbar
将被绘制在状态栏的中间位置。
该视图声明希望在xml中应用WindowInsets
:
android:fitsSystemWindows="true"
在此示例中,您无法将WindowInsets
应用于根布局,因为根布局将消耗WindowInsets
,并且ImageView
将被填充。
相反,您可以使用ViewCompat.setOnApplyWindowInsetsListener
将insets应用于工具栏:
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin =
insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
注意,当Toolbar
的根布局将WindowsInsets
传递给其子节点时,将调用此回调。像FrameLayout
,LinearLayout
这样的布局没有,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有一个关于这个东西的nice blog post at medium,还有Chris Banes的"Becoming a master window fitter🔧"演讲。
我还创建了关于a detailed article at Mediums的WindowInset
。
更多资源: