沉浸式体验
原创
©著作权归作者所有:来自51CTO博客作者wx5ba8dc11102bc的原创作品,请联系作者获取转载授权,否则将追究法律责任
问题
- 在实际开发过程中,弹出对话框之前是沉浸式布局,但是弹出对话框之后,持有对话框的Activity显示了状态栏,用户体验很差,所以总结一下沉浸式体验
沉浸式
- Android 沉浸式体验本质就是全屏化,整个屏幕显示都是服务内容,没有状态栏和导航栏,用户不会被系统元素打扰
- 期望效果 应用程序的界面占据整个屏幕,用户通过手势来与系统控件进行交互
SYSTEM_UI_FLAG
FLAG
| 意义
|
SYSTEM_UI_FLAG_FULLSCREEN
| 隐藏系统状态栏
|
SYSTEM_UI_FLAG_HIDE_NAVIGATION
| 隐藏系统导航栏
|
SYSTEM_UI_FLAG_LAYOUT_SCREEN
| 状态栏悬浮于Activity上
|
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| 导航栏悬浮于Activity之上
|
SYSTEM_UI_FLAG_LAYOUT_STABLE
| 保持系统UI稳定,不会随着SystemUI的变化而变化
|
SYSTEM_UI_FLAG_IMMERSIVE
| 沉浸模式
|
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| 沉浸模式且状态栏和导航栏出现片刻之后会自动隐藏
|
eg:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setSystemUiVisibility() 参数
参数
| 意义
|
View.SYSTEM_UI_FLAG_VISIBLE
| 显示状态栏
|
View.INVISIBLE
| 隐藏状态栏
|
View.SYSTEM_UI_FLAG_FULLSCREEN
| Activity全屏显示,且状态栏被覆盖掉
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| Activity全屏显示,但是状态栏不会被覆盖掉,而是正常显示,只是Activity顶端布 局会被覆盖住
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| 状态栏将布局顶部盖住
|
View.SYSTEM_UI_LAYOUT_FLAGS
| 全屏显示
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| 隐藏虚拟按键
|
View.SYSTEM_UI_FLAG_LOW_PROFILE
| 低电量模式下,状态栏的某些图标会被隐藏
|
eg:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN)
getSupportActionBar().hide();
- 状态栏透明 (5.0以上的系统才会支持需要增加判断)
getWindow().getDecorView().setSystemUIVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
getSupportActionBar().hide();
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
沉浸式体验
- 沉浸式体验不仅仅需要隐藏状态栏,导航栏也需要一起隐藏掉
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
getSupportActionBar().hide();
- 用户触摸屏幕任何位置都会导致设置的flag被清除了,不同地方设置UI Flag 效果会有不同的影响,在onResume()或者onWindowFocusChanged()函数中设置flag永久生效
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
//谷歌原生方法
private static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
View decor = activity.getWindow().getDecorView();
if (dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
- 该方法会带上FULL_SCREEN, 默认为全屏模式,需要在根布局中设置FitsSystemWindows=“true”
View content = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
if (content != null && !isUseFullScreenMode()) {
content.setFitsSystemWindows(true);
}
注意
//设置为透明色
getWindow().setStatusColor(Color.TRANSPARENT);
- 一般一个Activity中有四个Tab页,那么在Activityy中设置的全屏模式,四个Fragment都是全屏模式,如果某一个Fragment不需要全屏模式,就要在Fragment 中添加一个状态栏的高度的View
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);