Android 状态栏适配 以及 windowInsets探究

    View有一个属性是FitsSystemWindows,既可以通过在xml里设置android:fitsSystemWindows="true"设置,也可以通过View的setFitsSystemWindows方法设置,主要的作用是适配状态栏的高度,一旦设置了这个属性,Margin的设置就会失效,这个View的Margin值会变成windowInsets里的值(一般来说对于收集只有top值被改变了),除非有更顶层的View已经适配过了。所以这个属性通常是设置给布局的最顶层的View

Android 状态栏适配 以及 windowInsets探究

    当使用了这个属性之后,由于添加了topMargin,顶部会有一块位置空出来给状态栏,这一块颜色可能会与布局的颜色不一致,但是这可以通过设置View的background来改变。

    但是在给ViewPager设置FitsSystemWindows时却失败了,这与ViewPager的特殊设置有关,ViewPager重写了View的OnApplyWindowInsetsListener设置,这个设置的优先级比View处理windowInset的onApplyWindowInsets方法优先级要高,因此会先走这个方法。这是在ViewPager创建后的initViewpager方法中设置的,从设置的OnApplyWindowInsetsListener方法可以看到,ViewPager本身不会处理这个fitsSystemWindows这个属性,而是传递给子View,因此ViewPager设置这个属性并不生效。

Android 状态栏适配 以及 windowInsets探究

     另一个方面,ViewPager的子View应该都是通过adapter的getitem动态生成的,而对windowInsts的处理是在ViewRootImpl的performTraversals方法中,并且是在第一帧的处理内,其余的都是页面设置发生变化时才会调用,也就是说此时ViewPager的子View个数为0,所以就算在ViewPager的子View里设置了也不会立即生效,并不明白官方这样重新写ViewPager的windowInsets的作用,如果你有什么想法,欢迎评论。

Android 状态栏适配 以及 windowInsets探究

参考文章:

https://www.jianshu.com/p/986e2f8c98ff

介绍了windowInsets具体的分发过程