- 针对状态栏的操作,只针对4.4kitKat(含)以上的机型,部分国产rom会失效,目前发现的有华为的EMUI
- Activity必须是
noActionbar
主题
- 本文基于StatusBarUtils略作修改,感谢作者laobie
- 本文源码地址
相关属性重温
- FitsSystemWindows
在使用FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
、FLAG_TRANSLUCENT_STATUS
挤占了状态栏的高度的时候,我们的布局文件也跟着顶到了状态栏上。通过FitsSystemWindows
,系统会把app布局文件的paddingTop
修改成状态栏的高度,达到适配的效果

false顶到状态栏

true,paddingTop有一个状态栏高度
-
android.R.id.content
通过它我们可以在不需要知道ID的情况下,访问当前Activity根节点,一般是ContentFrameLayout
类型,通过((ViewGroup)findViewById(R.id.content)).getChildAt(0);
可以获取到我们布局xml的根节点
-
getDecorView()
通过他,我们可以获取到整个Window界面的最顶层View。我们用的很多的findViewById()
,就是基于这个DecorView
查找里面的子节点的。比如Activity主题是Theme.AppCompat.Light.NoActionBar
的组织层级如下,

noActionbarView层次.png
为什么嵌套那么深,因为各个层次可能都会有几个ViewStub
方便注入,只是我们现在的主题用不到就是空了。
下面开始实战了,一般我们用的比较多的是透明状态栏、设置状态栏颜色、DrawerLayout
盖在状态栏上三种。
1. 透明状态栏
这种情况一般用于把图片延伸到状态栏上,图片还分两种
- 作为
background
的全屏大图
- 作为
ImageView
控件存在,一般只占屏幕高度的一部分
这两种情况下的处理方式还不一样,具体看下文
上面的代码针对5.0以上或者4.4以上5.0以下的机型,让其状态栏透明、导航栏半透明,效果如下:

透明状态栏的结果是布局文件顶到了状态栏上
dump了下节点信息,我们发现布局的paddingTop从(50px状态栏高度)被修改成了0px。从而让图片延伸到了状态栏

不透明状态栏.png

透明状态栏.png
这种情况下,对app布局文件通过设置FitsSystemWindows
就可以完成适配了

app内容布局有了padding.png
注意!!要延伸到状态栏的图片,如果不是根节点的背景图,而是一个ImageView控件,那么就不能设置setFitsSystemWindows
了,原因参考上图红框。这种情况下,为了防止顶到状态栏,需要手动在xml里通过paddingTop
、marginTop
调整标题栏元素位置达到适配。类似下图

延伸到状态栏的图片是一个ImageView
2. 状态栏颜色
设置状态栏颜色的步骤和透明类似,差别在于5.0以下机型无法直接设置状态栏颜色,我们可以模拟一个纯色的View放到状态栏下面间接达到着色效果。放置的父层级我们选择DecorView
如果发现状态栏颜色设置无效,有可能是布局文件的root节点加了backgroundColor
所致
上面的代码判断DecorView下第0个View是不是我们自定义的StatusbarView类型,如果是则设置颜色,否则创建一个纯色控件插入到DecorView
内,同时布局内容上间距腾出给纯色控件。
3. DrawerLayout盖在状态栏上
DrawerLayout主要有两个子元素1:内容View 2:侧滑栏
侧滑栏必然要在内容View后面以覆盖前者

侧滑栏效果
所以我们要做的有2步
- 插入纯色控件到内容View(如果不是LinarLayout需要考虑内容View元素重新排列)
- DrawerLayout设置
fitSystemWindow=false
;以覆盖到状态栏上
代码如下:
总结:
上面三个方法,涵盖了app在大部分沉浸场景下的状态。在了解了底层实现后,我们也可以轻松在安卓上实现IOS的沉浸效果了,最低版本4.4 kitkat现在已经非常普及,随着MIUI、FlyME相继都升级到5.0、6.0以上,魅蓝、红米等大批国产中低端机型的都可以体验到这种酷炫的效果了。
本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/6671889.html,如需转载请自行联系原作者