Android7.0都已经正式发布了,现在再谈沉寖状态栏或者透明状态栏已经不是什么新鲜玩意了,IOS不用说,它们对于状态栏的支持比Android丰富而且规范的多,Android状态栏可以自定义颜色是从4.4开始,Android6.0以下的设备,状态栏也只支持深色背景白色icon的展示方式,少数手机类型除外。浅色状态栏深色图标仅限于少数版本如MIUI、Flyme、Android6.0,MIUI V6以上、Flyme4.0以上设备,这个不是本篇博文的重点。

什么是沉寖状态栏

从Android4.4开始Android手机可以支持自定义颜色的导航栏NavigationBar和状态栏StatusBar,网上多数开发者都把这种方式叫做沉寖式状态栏,知乎上面有篇帖子《为什么在国内会有很多用户把「透明栏」(Translucent Bars)称作 「沉浸式顶栏」?》。沉寖模式事实上是隐藏状态栏StatusBar和导航栏NavigationBar的展示模式,当然了在国内由于手机规格参差不齐,很多手机都是实体按键/电容按键,Immersive 和 Translucent 的 UI 呈现对于体验的影响基本没有差别。Android Developers有一篇文章专门介绍了沉寖模式Using Immersive Full-Screen Mode,

①Non-immersive mode ②Reminder bubble ③Immersive mode ④Sticky flag

上面交互是沉寖模式和非沉寖模式的交互,接下来我们介绍透明状态栏的设计风格,也许这两种交互最总呈现给用户的体验基本差不多,但是作为开发者来讲,我们应该知道这些功能终究是不同的,而不仅仅是为了咬文嚼字。

透明状态栏与导航栏

在设置状态栏和导航栏之前先进行一些基本设置,下面是style中部分样式

[代码]xml代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

@color/colorPrimary

@color/colorPrimaryDark

@color/colorAccent

@android:color/white

match_parent

?attr/actionBarSize

@color/colorPrimary

@style/ThemeOverlay.AppCompat.Dark.ActionBar

#fff

针对Android4.4以上的设备,Android支持透明状态栏,所以我们在资源文件value-v19中设置一下相关属性:

[代码]xml代码:1

2

3

4

true

true

设置完成后运行时在Android4.4以上的设备会出现内容区域与系统状态栏重叠的现象,

这种交互界面很显然不是我们所需要的,需要借助属性android:fitsSystemWindows="true"设置在布局文件的最上层,该属性主要是通过调整当前设置这个属性的view的padding去为我们的StatusBar留下空间。

这里有一点需要注意,在有些应用使用了侧滑菜单的地方,android:fitsSystemWindows="true"需要设置在内容区最上层布局上面,这时候如果设置在了DrawerLayout上面是不起作用的。

[代码]xml代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/drawerLayout"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:layout_width="match_parent"

android:fitsSystemWindows="true"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/toolbar"

style="@style/CustomToolbarStyle" />

...

设置之后再次运行仍然有问题,状态栏变成了浅灰色,Android4.4一直到Android5.0系统只给我们可以设置透明的属性,但是想要自定义颜色,还需要另觅其它方式。

现在整理一下系统版本的差异性,Android4.4开始可以设置状态栏为透明,但是直到Android5.1可以使用系统属性设置状态栏的颜色,而且这里所说的自定义颜色必须是深色背景的,因为图标是白色的,然后到Android6.0开始才可以设置浅色背景深色图标。为了这么一个状态栏或者导航栏,版本之间的差异竟然如此之大难免让人有些头大的感觉。但是在这里做交互优化,让状态栏跟整个应用看上去浑然一色,也确实会给用户带来很高的体验,所以还是值得一试的。在github上面已经有大神写了一个很牛X的库SystemBarTint,现在多数应用都是使用的这个库。

在开发时我们的BaseActivity中简单的设置一下就可以实现交互需要的效果。

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16public class BaseActivity    extends AppCompatActivity{

public SystemBarTintManager mgr;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mgr=new SystemBarTintManager(this);

mgr.setStatusBarTintEnabled(true);

mgr.setNavigationBarTintEnabled(true);

mgr.setStatusBarTintResource(R.color.colorPrimaryDark);

mgr.setNavigationBarTintResource(R.color.colorPrimaryDark);

}

}

SystemBarTint状态栏的实现机制

在上一篇博文有关Activity中View根布局的思考我们知道Activity根布局其实是一个DecorView,也就是页面中所能看到的组件全部都是DectorView的子View。在Android4.4以及Android5.0中我们不能设置状态栏的颜色,那么如果自定义一个View与系统状态栏的高度等高,然后通过DecorView直接添加进去就可以了,当然了这个View不可以覆盖状态栏的icon,使用DecorView添加就可以达到这个效果,因为DecorView是最顶级的布局了。

如何获取系统状态栏的高度呢,通过源代码可以查找到在frameworks\base\core\res\res\values\dimens.xml文件中有一个属性status_bar_height,只要获取到它的值就行了。

[代码]java代码:1

2

3

4

5

6

7

8

9private int getInternalDimensionSize(Resources   res, String key) {

int result = 0;

//key就是status_bar_height

int resourceId = res.getIdentifier(key, "dimen",   "android");

if (resourceId > 0) {

result   = res.getDimensionPixelSize(resourceId);

}

return result;

}

接下来新建一个View,将高度设置为状态栏的高度就可以了,还可以定义任意的色彩值。

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12private void initStatusBar()   {

Window win =   getWindow();

ViewGroup   decorViewGroup = (ViewGroup) win.getDecorView();

mStatusBarTintView   = new View(this);

Resources res =   getResources();

mStatusBarHeight   = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);

LayoutParams   params = new LayoutParams(LayoutParams.MATCH_PARENT,   mStatusBarHeight);

params.gravity =   Gravity.TOP;

mStatusBarTintView.setLayoutParams(params);

mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);

decorViewGroup.addView(mStatusBarTintView);

}

如果想自定义导航栏NavigationBar,实现机制与状态栏一致,SystemBarTint已经实现了,代码这里就不贴出来了。

Android5.1以上版本实现透明状态栏

等到有一天我们开发的应用只支持Android5.1以上版本时,SystemBarTint就可以完全抛弃了,因为Android系统本身就已经提供了API来实现透明状态栏或者导航栏的效果。虽然系统提供了设置透明状态栏和导航栏的API,但是使用的时候也是各种Flag林立,下面是对部分Flag的整理。

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

API 16开始提供,视图延伸至状态栏区域,状态栏上浮于视图之上。

View.SYSTEM_UI_FLAG_FULLSCREEN

API 16开始提供,状态栏隐藏,效果同设置WindowManager.LayoutParams.FLAG_FULLSCREEN

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

API 14开始提供,隐藏导航栏。

View.SYSTEM_UI_FLAG_LAYOUT_STABLE

API 16开始提供,保持整个View稳定, 常和控制System UI悬浮, 隐藏的Flags共用, 使View不会因为System UI的变化而重新layout。

View.SYSTEM_UI_FLAG_VISIBLE

API 14开始提供,默认标记。

View.SYSTEM_UI_FLAG_IMMERSIVE

API 19开始提供,沉浸模式, 隐藏状态栏和导航栏, 并且在第一次会弹泡提醒,并且在状态栏区域滑动可以呼出状态栏(这样会系统会清楚之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一个或两个同时设置。

View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY

API 19开始提供的,与上面唯一的区别是, 呼出隐藏的状态栏后不会清除之前设置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION标志,在一段时间后将再次隐藏系统栏)。

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS

API 14开始提供,跟在style资源文件设置android:windowTranslucentStatus为true效果一样,这里要注意了,字面意思是设置为透明模式,而事实上系统会提供最低限度的保护色,所以我们看到的是灰色的,而不是透明的。

WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION

API 14开始提供,跟在style资源文件设置android:windowTranslucentNavigation为true效果一样,其它跟状态栏类似。

WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS

API 21开始提供,Window负责系统工具栏的绘制如StatusBar和NavigationBar,其它方式会自动将系统工具栏置为透明色,Window上对应的区域会被具体的颜色值所取代,这些颜色通过window.getStatusBarColor()和方法window.getNavigationBarColor()设置,这也是为什么到Android5.1才开始可以使用系统API设置状态栏和导航栏的关键。

下面是一个设置系统工具栏的比较通用的代码:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14if(VERSION.SDK_INT >=   VERSION_CODES.LOLLIPOP) {

Window window =   getWindow();

//清除系统提供的默认保护色

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS

|   WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

//设置系统UI的显示方式

window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

|   View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

|   View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

//添加属性可以自定义设置系统工具栏颜色

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

window.setStatusBarColor(color_status_bar);

window.setNavigationBarColor(color_navigation_bar);

}

上面说过了在Android6.0里可以设置浅色状态栏深色图标,事实上设置也非诚简单,就一个FlagView.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,代码如下:

[代码]java代码:1

2

3

4

5//设置系统UI的显示方式

window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

|   View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

|   View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR//浅色状态栏标志位API 23

|   View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

android 状态栏隐藏 源码分析,Android 沉寖状态栏与透明状态栏相关推荐

  1. android doze模式源码分析,Android Doze模式启用和恢复详解

    从Android 6.0(API level 23)开始,Android提出了两个延长电池使用时间的省电特性给用户.用户管理可以在没有充电的情况下管理app的行为.当用户一段时间没有使用手机的时候,D ...

  2. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  3. 源码分析Android Handler是如何实现线程间通信的

    源码分析Android Handler是如何实现线程间通信的 Handler作为Android消息通信的基础,它的使用是每一个开发者都必须掌握的.开发者从一开始就被告知必须在主线程中进行UI操作.但H ...

  4. CTS(11)---android自动化测试CTS源码分析之一

    android自动化测试CTS源码分析之一 1, 概述 CTS(Compatibility Test Suite)全名兼容性测试,主要目的就是让Android设备开发商能够开发出兼容性更好的andro ...

  5. 从源码分析Android的Glide库的图片加载流程及特点

    转载:http://m.aspku.com/view-141093.html 这篇文章主要介绍了从源码分析Android的Glide库的图片加载流程及特点,Glide库是Android下一款人气很高的 ...

  6. android agps,Android应用开发Android GPS ——AGPS源码分析及配置

    本文将带你了解Android应用开发Android GPS --AGPS源码分析及配置,希望本文对大家学Android有所帮助. " Android Framework GPS --AGPS ...

  7. android gps源码分析,Android编程之Android GPS ——AGPS源码分析及配置

    本文主要介绍了Android编程的Android GPS --AGPS源码分析及配置,通过具体的分析以及源码,向大家展示了这些,希望对大家学习Android编程有所帮助. 1:冷启动指令: locat ...

  8. android view 源码分析,Android ViewPager源码详细分析

    1.问题 由于Android Framework源码很庞大,所以读源码必须带着问题来读!没有问题,创造问题再来读!否则很容易迷失在无数的方法与属性之中,最后无功而返. 那么,关于ViewPager有什 ...

  9. 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )

    文章目录 一.JobScheduler 提交任务 schedule 方法源码分析 二.schedule(JobInfo job, int uId) 方法 三.scheduleAsPackage 方法 ...

最新文章

  1. 20165235实验四 Android程序设计
  2. 视频编码中的RC(rate control)是什么?码率控制 CBR (Constant Bit Rate)、VBR (Variable Bit Rate)
  3. bme280 环境传感器开发板_盘一盘那些年我们常用的物联网开发板!
  4. 2019 年 8 月编程语言排行榜,Java涨幅不行!
  5. antd table排序 vue_商品品牌业务之Vue编写前端页面
  6. java akka_AKKA文档(java版)——什么是AKKA?
  7. java线程池读文件_多线程读取Java文件
  8. Jquery—重新认识Jquery中的html()方法
  9. DNT 3.1 快速安装手记
  10. Oracle活动会话历史(ASH)及报告解读
  11. kali wifi密码 破解
  12. FutureMapping:空间人工智能的计算结构
  13. 三星手机怎么看html5,三星手机查看硬件信息方法
  14. 该不该和教师一起去做项目
  15. Python攻关之模块(2)
  16. 服务器光信号闪红灯是什么意思,路由器上光信号闪红灯是什么意思
  17. win7中USB音箱没有声音解决办法
  18. Cocos 颜色混合BlendFunc
  19. 妙味课堂实战功能开发视频教程 3D翻转焦点图/瀑布流/拖拽购物车/模块化开发等实战教程
  20. 云函数 SCF 中 PHP 的一些入门坑

热门文章

  1. mysql if查询语句_MySQL if判断语句以及条件查询语句
  2. 关于各种转义符(转义字符串)
  3. linux图形界面鼠标变成小手_Linux常见服务类别及功能
  4. 深入理解java虚拟机:JVM高级特性与最佳实践第一部分走近Java第1章走近Java
  5. 如何使用Autodesk InfraWorks 360显示三维地图
  6. 调用海康摄像头实时识别数字牌数字
  7. 小米平板突然黑屏 摁哪也没反应
  8. 解决No module named flask的问题
  9. 并发编程系列之volatile关键字详解
  10. OpenCV实战(15)——轮廓检测详解