View类中设置UI元素效果的各个常量说明
以下各个常量全部都是用来作为setSystemUiVisibility(int)方法的参数使用的.
View.SYSTEM_UI_FLAG_VISIBLE(在API 14时被添加进来,单独设置有效)
默认值,请求状态栏可见
View.SYSTEM_UI_FLAG_LOW_PROFILE(在API 14时被添加进来,单独设置有效)
请求用户界面进入不引人注目的”低调”模式,在”低调”模式下,状态栏和/或导航图标会变暗,多用于游戏,书籍阅读器,视屏播放器或其他任何需要”沉浸模式”的应用程序
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION(在API 14时被添加进来,单独设置有效)
请求系统底部导航栏暂时隐藏.该标志比View.SYSTEM_UI_FLAG_LOW_PROFILE的效果更加突出,该标志只是让系统导航栏暂时隐藏,当用户与屏幕发生交互时,比如点击一下屏幕,该导航栏会再次显示.
View.SYSTEM_UI_FLAG_FULLSCREEN(在API 16时被添加进来,单独设置有效)
请求用户界面进入全屏幕模式,以便View的内容可以接管屏幕,同时仍允许用户与应用程序交互,该标志与WindowManager.LayoutParams.FLAG_FULLSCREEN具有相同的视觉效果,即状态栏将被隐藏,多用于游戏,书籍阅读器,视屏播放器或其他任何需要”沉浸模式”的应用程序
View.SYSTEM_UI_FLAG_LAYOUT_STABLE(在API 16时被添加进来,单独设置无效)
与其他SYSTEM_UI_FLAG一起使用,可以让其他的SYSTEM_UI_FLAG更加稳定,比如
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
但是在实际的测试中,好像并没有什么明显的效果.
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION(在API 16时被添加进来,单独设置有效)
请求用户界面延伸到状态栏(注意:该flag并不会隐藏底部导航栏),如果状态栏有颜色,则会遮住下方延伸的布局,所以通常设置状态栏颜色为透明.
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION ;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);//设置状态栏透明
}
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN(在API 16时被添加进来,单独设置有效)
和View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION效果相同,即请求用户界面延伸到状态栏(注意:该flag并不会隐藏底部导航栏),如果状态栏有颜色,则会遮住下方延伸的布局,所以通常设置状态栏颜色为透明.
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION ;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);//设置状态栏透明
}
View.SYSTEM_UI_FLAG_IMMERSIVE(在API 19时被添加进来,单独设置无效)
需要与View.SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用,对View.SYSTEM_UI_FLAG_HIDE_NAVIGATION的效果做更细致的修饰,上面在讲View.SYSTEM_UI_FLAG_HIDE_NAVIGATION的效果时说到,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION的效果只是让系统导航栏暂时隐藏,当用户与屏幕发生交互时,比如点击一下屏幕,该导航栏会再次显示.如果我们想在进行交互时,导航栏始终隐藏,则可以让View.SYSTEM_UI_FLAG_IMMERSIVE与View.SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用达到这种效果,
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(option);
}
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY(在API 19时被添加进来,单独设置无效)
该flag的效果与View.SYSTEM_UI_FLAG_IMMERSIVE类似,View.SYSTEM_UI_FLAG_IMMERSIVE虽然能保证在交互时,始终隐藏导航栏,但是如果用户不小心把导航栏再次滑动出来(当导航栏隐藏时,通过在屏幕底部向上滑动可以再次呼出导航栏),则这个导航栏将不再关闭,这有时体验很不好,而View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY就是解决这个问题的,View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY的效果与View.SYSTEM_UI_FLAG_IMMERSIVE类似,它的不同之处在于,如果用户不小心把导航栏滑动出来时,在一段时间内不操作导航栏,导航栏会再次自动隐藏.并且View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY可以和View.SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用,也可以和View.SYSTEM_UI_FLAG_FULLSCREEN结合使用.
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(option);
}
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR(在API 23时被添加进来,单独设置有效)
我们知道,每个设备的状态栏字体颜色一般都是白色或偏白色的,甚至状态栏中的系统图标也是白色或偏白色的,那么当我们的主内容是白色或偏白色且延伸到状态栏时,就会导致分辨不清状态栏的的内容,甚至直接看不见状态栏的内容,为了解决这个问题,Android在API 23中提供了这个FLAG,该FLAG的效果为:当状态栏背景是白色或偏白色或者其他亮色背景时,状态栏的字体颜色会变成黑色或偏黑色,图标会变成绿色或其他颜色,让其与亮色背景有更高的区分度,很容易识别状态栏中的内容,代码如下:
if (Build.VERSION.SDK_INT >= 23) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ;
decorView.setSystemUiVisibility(option);
}
需要注意的是,View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR的效果只对状态栏为亮色背景时有效,即状态栏的背景如果为黑色或者暗色调的背景,通过设置这个flag并不会让状态栏字体变成白色或其他亮色,而依然是黑色或者偏黑色字体.所以在使用这个FLAG的时候,要考虑清楚状态栏的背景颜色是不是亮色背景,如果不是则不要使用这个flag.因为该FALG并不会根据状态栏背景自动调整状态栏字体颜色.
WindowManager.LayoutParams类中设置UI元素效果的各个常量说明
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS(在API 19时被添加进来,单独设置有效)
效果为:半透明状态栏,用户界面延伸到状态栏.
状态栏的背景为半透明,不是全透明,目的就是为了当用户界面背景为白色或其他亮色时,状态栏的字体也能显示的很清楚.该效果也可以在style文件中通过windowTranslucentStatus属性定义,也可以继承Android中的主题获得,如
Theme_Holo_NoActionBar_TranslucentDecor
Theme_Holo_Light_NoActionBar_TranslucentDecor
Theme_DeviceDefault_NoActionBar_TranslucentDecor
Theme_DeviceDefault_Light_NoActionBar_TranslucentDecor
示例代码:
if (Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
WindowManager.LayoutParams.FLAG_FULLSCREEN(在API 1时被添加进来,单独设置有效)
效果为:隐藏状态栏,用户界面延伸到状态栏.当状态栏被滑出时,一段时间内不操作状态栏,状态栏会自动隐藏.
该效果也可以在style文件中通过windowFullscreen属性定义,也可以继承Android中的主题获得,如
Theme_NoTitleBar_Fullscreen
Theme_Black_NoTitleBar_Fullscreen
Theme_Light_NoTitleBar_Fullscreen
Theme_Holo_NoActionBar_Fullscreen
Theme_Holo_Light_NoActionBar_Fullscreen
Theme_DeviceDefault_NoActionBar_Fullscreen
Theme_DeviceDefault_LoightAoActionBar_Fullscreen
//这段代码的效果就是下面几行代码的综合效果,但这种方式更好,因为在API 1时就可以使用,而下面的方式需要到API 19才能使用.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(option);
}
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION(在API 19时被添加进来,单独设置有效)
效果为:底部导航栏背景为全透明,但导航按钮(返回按钮,回到桌面按钮,最近任务按钮)依然存在
该效果也可以在style文件中通过windowTranslucentNavigation属性定义,也可以继承Android中的主题获得,如
Theme_Holo_NoActionBar_TranslucentDecor
Theme_Holo_Light_NoActionBar_TranslucentDecor
Theme_DeviceDefault_NoActionBar_TranslucentDecor
Theme_DeviceDefault_Light_NoActionBar_TranslucentDecor
示例代码:
if (Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
常见的状态栏和导航栏需求
隐藏状态栏,保留导航栏,内容延伸到状态栏
方式一,方式二,方式三实现相同的效果,但在具体的交互上有点区别,具体的区别自己运行到设备上体会.
//方式一
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
getWindow().setStatusBarColor(Color.TRANSPARENT);
decorView.setSystemUiVisibility(option);
}
//方式二(推荐)
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(option);
}
//方式三(推荐)
if (Build.VERSION.SDK_INT >= 19) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
隐藏状态栏和导航栏,内容延伸到状态栏,真正全屏显示
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
getWindow().setStatusBarColor(Color.TRANSPARENT);
decorView.setSystemUiVisibility(option);
}
即使在交互过程中也保持状态栏和导航栏的隐藏
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(option);
}
即使在交互过程中也保持状态栏和导航栏的隐藏,如果必要时显示导航栏,一段时间后自动隐藏
if (Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(option);
}
总结:
所谓的”沉浸式状态栏”,核心原理其实都是把界面内容延伸到了状态栏中,这就可能导致状态栏内容遮住下方界面内容,解决这个问题的一个方式就是在界面内容的根布局中添加android:fitsSystemWindows=”true”即可.