天天看点

沉浸式状态栏实现郭霖的博客这样实现轮子

文章目录

  • 郭霖的博客这样实现
    • 透明状态栏
    • 隐藏导航栏
    • 真正的沉浸式模式
  • 轮子

郭霖的博客这样实现

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_FULLSCREEN

SYSTEM_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_STABLE

SYSTEM_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的使用说明

继续阅读