什么是WindowInsets?

问题描述 投票:15回答:2

我正在尝试了解Android操作系统,当我阅读Google I / O 2014应用程序时,我遇到了WindowInsets。如果有人能解释他们是什么,那将是一个很大的帮助。谢谢。

java android android-layout android-view windowinsets
2个回答
3
投票

您可以了解有关WindowInsets here.的所有信息WindowInsets为您提供了应用程序可用的窗口区域。它本身并没有多大用处。当你重写View.onApplyWindowInsets或实现View.OnApplyWindowInsetsListener时,这是真正的目的。你可以在这里阅读它们:View.onApplyWindowInsetsView.OnApplyWindowInsetsListener

侦听器以自定义方式在视图上应用窗口插入。

如果应用程序要将自定义策略应用于视图处理窗口插入的方式,则应用可以选择实现此接口。如果设置了OnApplyWindowInsetsListener,则将调用其onApplyWindowInsets方法,而不是View自己的onApplyWindowInsets方法。监听器可以选择调用参数View的onApplyWindowInsets方法,将View的正常行为作为其自身的一部分。

简而言之,覆盖它将允许您控制可用于View的窗口区域。


53
投票

WindowInsets是应用于窗口的系统视图(例如状态栏,导航栏)的插入(或大小)。

在具体的例子上很容易理解。想象这个场景:

enter image description here

现在,你不希望将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传递给其子节点时,将调用此回调。像FrameLayoutLinearLayout这样的布局没有,DrawerLayoutCoordinatorLayout

您可以对布局进行子类化,例如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

更多资源:

© www.soinside.com 2019 - 2024. All rights reserved.