Android沉浸式状态栏

Android 状态栏操做java

View类中设置UI元素效果的各个常量说明

如下各个常量所有都是用来做为setSystemUiVisibility(int)方法的参数使用的.android

View.SYSTEM_UI_FLAG_VISIBLE(在API 14时被添加进来,单独设置有效)

默认值,请求状态栏可见web

View.SYSTEM_UI_FLAG_LOW_PROFILE(在API 14时被添加进来,单独设置有效)

请求用户界面进入不引人注目的”低调”模式,在”低调”模式下,状态栏和/或导航图标会变暗,多用于游戏,书籍阅读器,视屏播放器或其余任何须要”沉浸模式”的应用程序api

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION(在API 14时被添加进来,单独设置有效)

请求系统底部导航栏暂时隐藏.该标志比View.SYSTEM_UI_FLAG_LOW_PROFILE的效果更加突出,该标志只是让系统导航栏暂时隐藏,当用户与屏幕发生交互时,好比点击一下屏幕,该导航栏会再次显示.ide

View.SYSTEM_UI_FLAG_FULLSCREEN(在API 16时被添加进来,单独设置有效)

请求用户界面进入全屏幕模式,以便View的内容能够接管屏幕,同时仍容许用户与应用程序交互,该标志与WindowManager.LayoutParams.FLAG_FULLSCREEN具备相同的视觉效果,即状态栏将被隐藏,多用于游戏,书籍阅读器,视屏播放器或其余任何须要”沉浸模式”的应用程序svg

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;

可是在实际的测试中,好像并无什么明显的效果.post

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”便可.