Android沉浸式状态栏

本文详细介绍了Android中实现沉浸式状态栏的各种方法,包括View类和WindowManager.LayoutParams类中的常量设置,如SYSTEM_UI_FLAG_VISIBLE、SYSTEM_UI_FLAG_FULLSCREEN等,并列举了常见状态栏和导航栏的需求及实现方式,帮助开发者实现全屏或半透明效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 状态栏操作

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值