沉浸式管理:让你的 APP 更优雅

7,430 阅读6分钟

作者博客

    http://www.jianshu.com/u/e01fe6ddfa1c


前言

       自从android4.4开始,android手机状态栏再也不是一成黑的时代,之前叫做变色龙,miui6发布会把他叫做沉浸式,之后大家就自然而然的接受了沉浸式这个名称,其实实际应该叫做Translucent Bar,即为透明状态栏。


       沉浸式实现原理其实是使整个activity布局延伸到整个屏幕,然后使状态栏变成透明色,有些手机会有导航栏,同样也可以把导航栏变成透明色,这样会使一些app更加美观。


先看两个概念

状态栏 

导航栏

废话不多说了,直接看GIF

引入

github仓库地址:https://github.com/gyf-dev/ImmersionBar

特性

基本介绍

基础用法,建议在BaseActivity里调用

高级用法,如果基础用法不能满足你的需求,可以试试这里的方法


详细介绍

解决状态栏和布局顶部重合


上面已经说了,沉浸式原理就是使整个布局延伸到状态栏和导航栏,既然这样必然导致一个问题,就是状态栏和布局顶部重叠,直接看图

眼神好的同学已经看到上图中给了四种解决方案啦,在这里我就说一


1.使用dimen自定义状态栏高度

使用系统的fitsSystemWindows属性

使用ImmersionBar的fitsSystemWindows(boolean fits)方法

使用ImmersionBar的statusBarView(View view)方法

总结:这四种方法,任选其一使用就可以了,不要一起使用哦,根据项目而定,比如有侧边栏的,建议使用第1种或者第4种,最后来一张效果图

图片状态栏+彩色导航栏

全屏图片

彩色状态栏+彩色导航栏

结合DrawerLayout使用

结合Fragment使用(fragment+viewpager)

         为了使每个fragment都可以设置不同的沉浸式样式,这里给出两种解决方式


1.使用viewpager的addOnPageChangeListener方法,直接上代码

2.fragment继承库里的ImmersionFragment,然后在immersionInit()方法中初始化,直接上代码

1和2实现效果相同,如下

结合侧滑返回使用

修改状态栏字体颜色为深色

设置状态栏和导航栏透明度

解决EditText和软键盘的问题

特性总结

       ImmersionBar除了这些特性之外,还有其他特性哦,这里就不一一指出了,大家参考高级用法的注释,可以去实现看看哦,下面就来分析源码吧


源码分析

  本库采用类似建造者模式来完成,只为了方便大家更灵活的去设置状态栏和导航栏风格。实现沉浸式是分为两块,一块是android5.0以上,一块是android4.4,这两块实现原理完全不一样,在讲解原理之前先看几个概念,下面需要用到

  • View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(恢复到有状态的正常情况)。

  • View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。

  • View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。

  • View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。

  • View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

  • View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

  • View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。

  • View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。

  • android 5.0以上核心代码

       Android自5.0起,为我们提供了设置状态栏和导航栏颜色的API,我们可以自己设置状态栏和导航栏的颜色。本框架在android5.0以上就是采用官方api完成的,网上关于5.0以上的实现基本都是这样,在这里就不多说了,在这里只说一点,就是设置颜色的时候不是直接填入开发者传入的颜色值,而是采用v4包下的ColorUtils.blendARGB()方法来设置,为什么这样设计呢?有些app的状态栏并不是和标题栏颜色相同,稍微有些色差,所以在这里开发者只需要通过blendARGB()设置透明度就可以形成这种色差,而且还可以指定两种颜色之间的色差值,方便大家,android4.4上亦是如此。请看以下代码:

  • android 4.4核心代码

           在4.4里就没有5.0以上这些api了,只能设置透明状态栏和导航栏,而且设置透明导航栏之后,底部布局会被导航栏遮住,那怎么办呢?好吧,只能自己写代码去实现啦。再说之前,说说我的一个思路吧。现在是2.x.x版本,在1.x.x版本的时候,4.4中实现沉浸式是引用大家非常熟悉的一个库SystemBarTint(不推荐使用了,很久没人维护了)来实现的,但是后来发现一个严重的问题,对于有导航栏的手机,设置导航栏颜色的时候,底部布局会被导航栏遮住,除此之外还有一个小问题就是当用户设置状态栏为透明色的时候,不能时刻改变bar的颜色值,are you kidding?既然出现这样的问题,就想着怎么去解决吧!就这样,我乖乖去看看SystemBarTint的源代码,哦!原理如此,发现SystemBarTint库的实现就是在状态栏和导航栏的位置自定义了可以改变背景颜色的view,然后通过window.getDecorView()得到根布局,把刚才创建的view添加进去,既然这样,为何不自己也写一个,顺便把刚才说到导航栏的问题也解决一下呢。解决方法如下代码,在这里通过注释的方法向大家说明。这里代码只是片段,不可以直接拷贝到自己的项目中

  • 状态栏字体颜色

           沉浸式原理说完了,在看看状态栏字体颜色怎么去修改吧,在android 6.0以上系统为我们提供了相关的api来设置状态栏字体颜色,如下

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
  •        但是对于一些第三方rom包来说,系统api就没办法实现了,还好小米和魅族公开了各自的实现方法,如下:

    • MIUI:


    • flymeOS:


  • 状态栏和导航栏的隐藏

       android 4.1以上支持状态栏和导航栏隐藏

总结

       至此,ImmersionBar库的用法与原理都讲完了。网上关于沉浸式的介绍铺天盖地,但是很少有人把它们封装起来,当开发者调用的时候还得自己去写大量代码,消耗大家时间。写这个库的目的就是方便大家的开发,解决大家在沉浸式方面出现的问题。如果还有不懂得地方可以去demo里看看,或者直接底下留言!