Android 透明状态栏

来源:互联网 发布:js 图片跟随鼠标移动 编辑:程序博客网 时间:2024/06/08 11:00

写这篇文实在是因为网上流传了太多鱼龙混杂的文章,各种东拼西凑,而且只讲方法不讲道理。所以我尽量做到,最后给出的解决方案是能看得懂的。

这里不讨论“沉浸式”“沉浸式状态栏”“透明状态栏”的定义,能知道我这篇讲的是“透明状态栏”,说明这些概念你已经搞清楚了。


真正意义上的(全)透明状态栏,只有Android 5.0及以上才支持

关于windowTranslucentStatus
该style属性以及windowTranslucentNavigation,是在Android 4.4中被引入的。参考
在Android 4.4上,如果为主题启用了这两个属性,状态栏和导航栏部分会变为由黑色开始的透明渐变;在Android 5.0以上,启用了这两个属性,状态栏和导航栏会变为纯粹的半透明:


注意事项:
    1.启用透明状态栏,布局将填充系统状态栏后面的区域,所以必须为不应被系统状态栏覆盖的布局部分启用 fitsSystemWindows。
    2.设置windowTranslucentStatus,会自动为window添加View.SYSTEM_UI_FLAG_LAYOUT_STABLEView.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN这两个flag。

关于statusBarColor
该Window的方法在Android 5.0中被引入。
官方对该API的介绍:
Sets the color of the status bar to color. For this to take effect, the window must be drawing the system bar backgrounds withFLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS andFLAG_TRANSLUCENT_STATUSmust not be set. If color is not opaque, consider settingSYSTEM_UI_FLAG_LAYOUT_STABLEandSYSTEM_UI_FLAG_LAYOUT_FULLSCREEN.
The transitionName for the view background will be "android:status:background".
主要是几点:
    1.该方法可以设置状态栏的颜色。为了使该方法生效,FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS要启用,FLAG_TRANSLUCENT_STATUS要禁用,即保持这两个flag的默认值。
    2.如果颜色值不是不透明的(实际上就是有透明度,但不一定完全透明),要设置SYSTEM_UI_FLAG_LAYOUT_STABLE和SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN。
经过测试:
 设置两个flag不设置两个flagcolor透明状态栏透明,且布局填充到状态栏区域状态栏不透明(color叠加到纯白色背景上),布局正常color不透明状态栏不透明,布局填充到状态栏区域状态栏不透明,布局正常
由测试结果可以看出,这两个flag的作用主要是将布局拉到状态栏的区域,同时透明化状态栏。单纯设置color的颜色,状态栏仍然占据原来的位置,所以不透明。
    3.默认情况下,android:statusBarColor 将继承 android:colorPrimaryDark 的值。

透明状态栏的具体实现
综上,可以得到设置透明状态栏的方法(仅Android 5.0以上)。
    1.设置状态栏为透明色
 /res/values-v21/styles.xml
<item name="android:statusBarColor">@android:color/transparent</item>
或者在代码中(因为只有Android 5.0以上才有setStatusBarColor方法,所以调用之前一定要检查系统版本)
if (Build.VERSION.SDK_INT >= 21) {    View decorView = getWindow().getDecorView();    getWindow().setStatusBarColor(Color.TRANSPARENT);}
    2.设置相应的window flag
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
结合1当中,纯代码实现:
if (Build.VERSION.SDK_INT >= 21) {    View decorView = getWindow().getDecorView();    int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;    decorView.setSystemUiVisibility(option);    getWindow().setStatusBarColor(Color.TRANSPARENT);}
    3.在需要的地方,设置android:fitsSystemWindows="true",让系统根据状态栏的高度设置一个合适的padding。

其他
有两种情况:
    1.MIUI等在Android 4.4上自己实现的透明状态栏,在设置windowTranslucentStatus之后,呈现的不是渐变透明,而是全透明。
    2.当UI布局的标题栏背景为纯色,Android 5.0以上依然可以使用上面的方法设置状态栏为透明。但是更简单的方法是,直接设置状态栏的颜色为标题栏的颜色,视觉效果一样。
    3.对于导航栏,与之对应的有navigationBarColor属性,setNavigationBarColor方法,且有类似的使用规则:
Sets the color of the navigation bar to . For this to take effect, the window must be drawing the system bar backgrounds with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS and FLAG_TRANSLUCENT_NAVIGATION must not be set. If is not opaque, consider setting SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION.
The transitionName for the view background will be "android:navigation:background".


参考

https://stackoverflow.com/a/28041425/4083396

https://developer.android.com/training/material/theme.html#StatusBar

https://developer.android.com/about/versions/android-4.4.html#UI

https://www.zhihu.com/question/31468556/answer/52169988

http://www.jianshu.com/p/28f1954812b3

http://blog.csdn.net/guolin_blog/article/details/51763825

原创粉丝点击