沉浸式状态栏实现

郭霖的博客这样实现

Android状态栏微技巧,带你真正理解沉浸式模式

透明状态栏

新建一个项目,只放一张图片
在这里插入图片描述
可以看到 状态栏、ActionBar、底部导航栏都显示,现在修改 Activity 中代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
        getSupportActionBar().hide();
    }
}

重新运行程序,可以看到 状态栏、ActionBar 都隐藏了
在这里插入图片描述
这里先调用getWindow().getDecorView()方法获取到了当前界面的 DecorView,然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏

另外,根据Android的设计建议,ActionBar 是不应该独立于状态栏而单独显示的,因此状态栏如果隐藏了,我们同时也需要调用 ActionBar 的hide()方法将ActionBar也进行隐藏

虽说这才是正统的沉浸式含义,但有些朋友可能想实现的就是饿了么那样的状态栏效果,而不是直接把整个系统状态栏给隐藏掉,那么又该如何实现呢?

在这里插入图片描述
方法一:
修改代码如下:

View decorView = getWindow().getDecorView();
        int options = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(options);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getSupportActionBar().hide();

在这里插入图片描述

我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREENSYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用 Window 的setStatusBarColor()方法将状态栏设置成透明色就可以了

方法二:
可以用以下代码完成相同的效果

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getSupportActionBar().hide();

当 window 的FLAG_TRANSLUCENT_STATUS属性有效的时候,会自动设置 system ui visibility 的标志SYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

当然也可以在 style 中设置属性 windowTranslucentStatus

android:windowTranslucentStatus

方法三:

如果有 actionbar 的话,可以设置 状态栏和 actionbar 颜色相同来实现

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(Color.parseColor("#2F90E5"));

设置了FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,表明会 Window 负责系统 bar的 background 绘制,绘制透明背景的系统 bar(状态栏和导航栏),然后用getStatusBarColor()getNavigationBarColor()的颜色填充相应的区域。这就是 Android 5.0 以上实现沉浸式导航栏的原理

当然 theme 中也可以设置相应属性来设置样式

    <style name="Theme.TestApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="android:statusBarColor">#2F90E5</item>
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

隐藏导航栏

隐藏导航栏也就是使用了不同的UI Flag而已,修改MainActivity中的代码,如下所示:

View decorView = getWindow().getDecorView();
        int options = View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        decorView.setSystemUiVisibility(options);
        getSupportActionBar().hide();

在这里插入图片描述
好像是完全全屏了,但是我们触摸屏幕的任意位置都会退出全屏

除了隐藏导航栏之外,我们同样也可以实现和刚才透明状态栏类似的效果,制作一个透明导航栏:

View decorView = getWindow().getDecorView();
        int options = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(options);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getSupportActionBar().hide();

在这里插入图片描述
这里使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用系统导航栏的空间,然后又调用了setNavigationBarColor()方法将导航栏设置成透明色

真正的沉浸式模式

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        View decorView = getWindow().getDecorView();
        decorView.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);
    }
}

在这里插入图片描述

可以看到,界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,只需要在屏幕顶部向下拉,或者在屏幕底部向上拉,状态栏和导航栏就会显示出来,此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,状态栏和导航栏又会自动隐藏起来,重新回到全屏状态

这就是最标准的沉浸式模式

轮子

Github:ImmersionBar
ImmersionBar的使用说明

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值