Day20-沉浸式状态栏

2017-09-22  本文已影响260人  我不是死胖子

概念

  1. 全屏模式
  2. 变色状态栏模式
  3. 背景全屏+变色状态栏模式
  4. 图片全屏+变色状态栏模式
  5. ContentView: activity.findViewById(Window.ID_ANDROID_CONTENT) 获取的 View , 即 setContentView 方法所设置的 View, 实质为 FrameLayout.
  6. ContentParent: ContentView 的 parent , 实质为 LinearLayout.
  7. ChildView: ContentView 的第一个子 View ,即布局文件中的 layout.

相关函数

  1. fitsSystemWindows, 该属性可以设置是否为系统 View 预留出空间, 当设置为 true 时,会预留出状态栏的空间.
  2. ContentView, 实质为 ContentFrameLayout, 但是它的 dispatchFitSystemWindows 重写了 fitsSystemWindows 方法, 所以对其设置 fitsSystemWindows 无效.
  3. ContentParent, 实质为 FitWindowsLinearLayout, 里面第一个 View 是 ViewStubCompat, 如果主题没有设置 title ,它就不会 inflate .第二个 View 就是 ContentView.
  4. setClipToPadding: 保持padding, true为保持

概述

总结一下:
可以看出 DecorView 作为根布局, 持有一个 LinearLayout,
* 5.0在LinearLayout下持有四个View, 两个系统级的 View(StatusBar 和 Navigation), 和两个 FrameLayout, 一个是ViewStub, 一个是给了 ContentFraneLayout + ActionBar(当设置不需要 ActionBar 时, 是ViewStubCompat).
* 4.4在LinearLayout下只有两个View, 可以推出5.0可以直接```setStatusBarColor```是因为多了这俩view, 那我们只要在 LinearLayout 中插入一个 view 就可以学着5.0的样子, 让ContentFraneLayout下移.

4.4 以下放弃

4.4.4 kitcat

谷歌在 Android 的 Window 属性里添加了可以让状态栏和导航栏被穿透(ContentView覆盖StatusBar)的属性

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

全屏模式

  1. 给 Window 添加 FLAG_TRANSLUCENT_STATUS
  2. 给 ContentView 的子 view 设置 setFitsSystemWindows

FLAG_TRANSLUCENT_STATUS 效果:
自动设置了 SYSTEM_UI_FLAG_LAYOUT_STABLE 和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 让 ContentView 满屏

变色状态栏模式

  1. 给 Window 添加 FLAG_TRANSLUCENT_STATUS
  2. 给 DecorView 添加一个伪状态栏
  3. 给 ContentView 的子 view 全部设置 setFitsSystemWindows

背景全屏+变色状态栏模式

  1. 给 Window 添加 FLAG_TRANSLUCENT_STATUS
  2. 给 ContentView 的子 view 全部设置 fitsSystemWindows, 空出StatusBar的高给伪状态栏
  3. 给 ContentView 添加一个伪 StatusBar

图片全屏+变色状态栏模式

  1. 给 Window 添加 FLAG_TRANSLUCENT_STATUS
  2. 给 ContentView 添加一个伪 StatusBar
  3. 如果是 Imageview 浮在布局上, 即下一个布局也怼上了 StatusBar, 需要手动给后续布局加 topMargin

5.0 LOLLIPOP

比起 4.4, 不需要 FLAG_TRANSLUCENT_STATUS, 因为谷歌又�提供了setStatusBarColor, 不过默认 StatusBar 的会添加半透明灰条, 所以还得改下 StatusBar 的颜色为透明

全屏模式:

  1. 给 Window 设置FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 让 ContentView 怼到顶
  2. 给 Window 设置setStatusBarColor 修改透明颜色

变色状态栏模式

  1. 给 Window 设置FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 让 ContentView 怼到顶
  2. 给 windiw 设置setStatusBarColor 修改指定颜色

背景全屏+变色状态栏模式

  1. 给 Window 设置FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 让 ContentView 怼到顶
  2. 给 Window 设置setStatusBarColor 修改透明颜色
  3. 给 ContentView 的子 view 全部设置 fitsSystemWindows, 空出StatusBar的高给伪状态栏
  4. 给 ContentView 添加伪 StatusBar

图片全屏+变色状态栏模式(3,4步和4.4处理方式一样)

  1. 给 StatusBar 设置透明
  2. 给 DecorView 设置 SYSTEM_UI_FLAG_LAYOUT_STABLE 和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

是不是很眼熟, 对, 就是FLAG_TRANSLUCENT_STATUS自动附带的设置, 不过5.0 可以直接改 StatusBar 的颜色了, 不需要 TRANSLUCENT_STATUS

  1. 给 ContentView 添加伪 StatusBar
  2. 如果是 Imageview 浮在布局上, 即下一个布局也怼上了 StatusBar, 需要手动给后续布局加 topMargin

特殊需求:

如果一个 StatusBar 可变色的 acitivy, 加入图片全屏 + 变色StatusBar 的 fragment/或 StatusBar 联动的 fragment 也就是当 StatusBar 和 fragment 一体, 建议�此 fragment 替换为 activity, 虽然可以�实现, 但是需要页面绘制两遍不说, 二是 StatusBar 是在页面出现后加入的. 如果项目一开始就有这个需求, 那么在全部fragment�的xml中加状态栏高的view

fragment中的沉浸式

思路:
如果需要 StatusBar 和 fragment 一起联动, 需要多两步

  1. 在fragment的xml中添加一个view(StatusBar_view_height).
  2. xml中设置StatusBar_view_height的值
 - <dimen name="StatusBar_view_height">0dp</dimen>
v19 - <dimen name="StatusBar_view_height">25dp</dimen>
vw820dp - <dimen name="activity_horizontal_margin">64dp</dimen>

抽屉

和activity一个处理思路

实现

Tips:
自定义Theme 运行时是先找自己版本号对应的styles, 如果没有那就去找无版本号的styles里的. 所以一定要在无版本号的styles里写上自定义Theme, 哪怕里面没有东西, 不然直接崩
推荐通过代码修改, 单纯的依靠theme也可以, 但是不如代码直观, 也不便于控制

1. theme中需要做的铺垫

a. 通过代码里设置

  1. 去掉自带actionBar
    <item name="WindowActionBar">false</item>
    <item name="android:WindowActionBar">false</item>
    <item name="WindowNoTitle">true</item>
    
  2. 去掉打开时先加载一闪而过的 空白背景+默认StatusBar 的默认背景
    <item name="android:WindowIsTranslucent">true</item>
    <item name="android:WindowBackground">@android:color/transparent</item>
    

2. 代码:

https://github.com/laobie/StatusBarUtil

踩坑

TODO

参考

上一篇下一篇

猜你喜欢

热点阅读