我正在尝试学习关于Android操作系统,当我阅读Google I/O 2014应用程序时,我遇到了WindowInsets
。如果有人能够解释它们是什么,那将是一大帮助。谢谢。
WindowInsets
。如果有人能够解释这是什么,那将会非常有帮助。谢谢。我正在尝试学习关于Android操作系统,当我阅读Google I/O 2014应用程序时,我遇到了WindowInsets
。如果有人能够解释它们是什么,那将是一大帮助。谢谢。
WindowInsets
。如果有人能够解释这是什么,那将会非常有帮助。谢谢。WindowInsets
是系统视图(例如状态栏、导航栏)的嵌入(或大小),应用于窗口。
通过具体示例很容易理解。想象一下这种情况:
现在,您不希望将WindowInsets
应用于背景ImageView
,因为这样ImageView
将被状态栏高度填充。
但是您希望将插图应用于Toolbar
,否则Toolbar
将绘制在状态栏中间某个位置。
该视图通过以下方式在xml中声明希望应用WindowInsets
:
android:fitsSystemWindows="true"
WindowInsets
应用于根布局,因为根布局会消耗WindowInsets
,并且ImageView
会填充。
相反,您可以使用ViewCompat.setOnApplyWindowInsetsListener
来应用插图到工具栏:
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;
}
有一篇关于这方面的好博客文章在medium上由Ian Lake撰写, 还有Chris Banes撰写的"成为窗户安装大师"演示在此处。
我还创建了一篇详细的Medium文章关于WindowInset的内容。
更多资源:
Android系统使用屏幕的某些部分来渲染自己的内容,例如顶部的状态栏和底部的导航栏。如果应用程序想要在底部栏后面进行渲染,它应该考虑到底部栏占用的区域,否则应用程序界面将与系统界面冲突,会出现类似于这样的情况¹:
在上面的图像中,应该向FAB按钮添加额外的底边距,以使按钮不与底部栏相交。WindowInsets API允许您获取系统UI消耗的底部插入等信息。您经常会遇到fitsSystemWindows
属性,其具有类似的目的,请参阅this answer了解有关属性的更多信息以及何时应该使用它而不是WindowInsets
。您还可以查看这篇很棒的文章:Gesture Navigation: handling visual overlaps (II)。等等,什么是 Gesture Navigation ?¹ 该图片来自于手势导航:边缘到边缘(I)文章
² 该图片来自于手势导航:处理手势冲突(III)文章
WindowInsets
为您提供应用程序可用的窗口区域。它本身并没有什么用处。当您覆盖 View.onApplyWindowInsets
或实现 View.OnApplyWindowInsetsListener
时,才能发挥其真正的作用。您可以在这里阅读有关它们的信息:View.onApplyWindowInsets 和 View.OnApplyWindowInsetsListener。
自定义视图应用窗口插图的侦听器。
如果应用程序想要以自定义方式处理窗口插图,则可以选择实现此接口。如果设置了 OnApplyWindowInsetsListener,则会调用其 onApplyWindowInsets 方法,而不是 View 自己的 onApplyWindowInsets 方法。侦听器可能选择调用参数 View 的 onApplyWindowInsets 方法,以将 View 的正常行为作为其自身的一部分应用。
简而言之,覆盖此方法将让您控制您的视图可用的窗口区域。