Android沉浸式模式的实现

什么是沉浸式模式

Android 4.4 (API Level 19)引入一个新的概念——“沉浸式模式”,即真正的全屏模式:SystemUI(StatusBar和NavigationBar)也都被隐藏,具体可以参考Android开发者官网的介绍:Using Immersive Full-Screen Mode
如果大家已经下载Android SDK的文档,那么也可以查看SDK目录下的文档:docs\training\system-ui\index.html
下图来自android开发者官网对沉浸式介绍的文档

沉浸式模式的实现

沉浸式模式的实现,在Android不同版本是有差异的。

Android 4.4 (API Level 19)及以上

针对Android 4.4 (API Level 19)及以上的版本,上面的版本已经介绍了如何实现沉浸式模式:

 int systemUiVisibility = decor.getSystemUiVisibility();
 int flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
systemUiVisibility |= flags;
activity.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);             

Android 4.4 以下

直接给Window添加全屏标记位

activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

同时,为了不让布局因SystemUI的可见或隐藏而重新layout,可以给Window添加FLAG_LAYOUT_IN_SCREEN和FLAG_LAYOUT_NO_LIMITS这2个标记位,这样SystemUI出现时候是overlay在布局内容的上面。如:

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);    
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

效果如下:

取消沉浸式模式

Android 4.4 (API Level 19)及以上

int systemUiVisibility = decor.getSystemUiVisibility();
        int flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
systemUiVisibility &= ~flags;
activity.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);             

考虑Activity所使用的主题和背景,如有必要,可以设置SystemUI为半透明,否则取消沉浸式模式后SystemUI可能看不清:

// Translucent status bar
        window.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        // Translucent navigation bar
        window.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

Android 4.4 以下

activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

判断是否处于沉浸式模式

Android 4.4 (API Level 19)及以上

 View decor = activity.getWindow().getDecorView();
        int systemUiVisibility = decor.getSystemUiVisibility();
        int flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        return (systemUiVisibility & flags) == flags;

Android 4.4下

return (activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) > 0;

监听 沉浸式模式变化

有多种方案:

  • OnSystemUiVisibilityChangeListener
View decorView = getWindow().getDecorView();  
     decorView.setOnSystemUiVisibilityChangeListener(this::onSystemUiVisibilityChange);

void onSystemUiVisibilityChange(int visibility) {
    Log.d(TAG, "visibility=" + visibility);
}

该方案仅适用于Android 4.4 (API Level 19)及以上。

  • ViewTreeObserver.OnGlobalLayoutListener
decorView.getViewTreeObserver().addOnGlobalLayoutListener(this::onGlobalLayout);

void onGlobalLayout() {
        Log.d(TAG, "isFullScreenActivity=" + isFullScreenActivity(ImmersiveModeActivity.this));
}

这是通用方案。

Demo源码

Demo源码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值