@Author: Luzhuo (http://luzhuo.me/blog)
优质的用户体验, 状态栏和导航栏的展示方式起到画龙点睛的作用.
前提样式:
使用系统的默认样式
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
- "colorPrimary"
>@color/colorPrimary
- "colorPrimaryDark">@color/colorPrimaryDark
- "colorAccent">@color/colorAccent
style>
方式 | StatusBar | NavigationBar | 自动隐藏 | Description |
---|---|---|---|---|
FLAG_FULLSCREEN | √ | × | √ | 状态栏全屏(叠加), 自动隐藏 |
√ | × | × | 减少状态栏元素, 不隐藏 | |
SYSTEM_UI_FLAG_LOW_PROFILE | √ | × | × | 减少状态栏元素, 不隐藏 |
SYSTEM_UI_FLAG_HIDE_NAVIGATION | × | √ | × | 隐藏导航栏, 任意位置触发, 不隐藏 |
SYSTEM_UI_FLAG_FULLSCREEN | √ | × | × | 状态栏全屏(不叠加), 不隐藏 |
SYSTEM_UI_FLAG_IMMERSIVE_STICKY + … | √ | √ | √ | 解决不能自动隐藏的问题 |
SYSTEM_UI_FLAG_IMMERSIVE + … | × | √ | × | 解决任意位置触发的问题, 不隐藏 |
全屏, 从Android 3.0 及 更早 开始支持隐藏StatusBar的方式
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
全屏后, 会隐藏StatusBar, 用户在StatusBar向下滑动后会显示, 过会儿会自动隐藏.
在 Android3.0 起添加了该方式, 并在Android 4.0 将其废弃.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
decorView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN );
调用代码后, 会将部分不重要的信息隐藏, 用户操作StatusBar后会将标志清除, 若需再次隐藏, 则要再次调用代码.
Android 3.0 的 STATUS_BAR_VISIBLE 被改成了 SYSTEM_UI_FLAG_VISIBLE, STATUS_BAR_HIDDEN 被改成了 SYSTEM_UI_FLAG_LOW_PROFILE, 其效果都是一样的.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
这里重点说下 导航栏.
Android 4.0 起, 引入了 Navigationbar, 也开启了对其的控制.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
调用代码后, 将 NavigationBar 隐藏, 用户交互任意位置将触发, 触发后不会自动隐藏, 若需隐藏则需要再次调用代码.
在 Android4.1 及 以上, 使用 SYSTEM_UI_FLAG_FULLSCREEN 代替了 LayoutParams.FLAG_FULLSCREEN, 但是 LayoutParams.FLAG_FULLSCREEN 为什么没有被废弃呢, 其实这里的效果还是有略微差别的.
// 旧方式的全屏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 新方式的全屏
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
差别主要表现在:
1.旧方式是叠加的.
2.新方式是不叠加的.
沉浸式全屏
沉浸式全屏, 就是将内容延伸到 StatusBar 和 NavigationBar 下, 也是目前最流行的设计方式.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
接下来你只需把 StatusBar 和 NavigationBar 设置为透明就好了.
稳定布局
有时将 StatusBar 和 NavigationBar 隐藏后, 但是需要把他们的位置留出来(稳定住), 这时就需要 SYSTEM_UI_FLAG_LAYOUT_STABLE .
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
用户点击任意位置, 标记将被清除, 若要全屏需要再次调用代码.
在之前的方案中, StatusBar 被用户触发后, 不会自动隐藏, NavigationBar 在用户点击任意位置时触发. Android 4.4 主要解决这些问题.
StatusBar 和 NavigationBar 自动隐藏
SYSTEM_UI_FLAG_IMMERSIVE_STICKY 结合 SYSTEM_UI_FLAG_FULLSCREEN 和 SYSTEM_UI_FLAG_HIDE_NAVIGATION 使用, 能够让他们自动隐藏.
他们会变成半透明, 会叠加在内容之上.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
用户触发会后自动隐藏.
NavigationBar 只在需要时弹出
SYSTEM_UI_FLAG_IMMERSIVE 结合 SYSTEM_UI_FLAG_HIDE_NAVIGATION 使用, 使其只在用户主动触发 NavigationBar 时才显示, 而不是点击任意位置.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE);
用户触发后, 不会自动隐藏, 需要再次调用代码.
Android4.4 引入了透明色 (FLAG_TRANSLUCENT_STATUS / FLAG_TRANSLUCENT_NAVIGATION).
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
使用了透明色之后, 内容会至于Bar的下方.
Android5.0 支持自定义 StatusBar的背景色.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(getResources().getColor(R.color.colorAccent));
getWindow().setNavigationBarColor(getResources().getColor(R.color.colorPrimaryDark));
除了改背景色, Android6.0 支持修改图标和文字的颜色.
当然颜色并不是让你随便改, 默认的颜色是白色的, 如果设置了白色等亮色的背景, 就需要把文字设置成黑色.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
// 需求: StatusBar 透明, 白字, 内容至于其下, 无自动隐藏
// NavigationBar 白色, 黑字, 无需自动隐藏
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
// Navigation 黑字
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
// 内容至于 StatusBar 其下
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
// 使其能修改颜色
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // StatusBar 透明
getWindow().setNavigationBarColor(Color.WHITE); // Navigation 白色