首先声明一下这个叫法应该是不对的,Translucent翻译过来的是半透明效果,不是IOS的那种什么沉浸式

1. 概念

首先要明确1个概念,在android上,“沉浸式”叫沉浸式全屏模式以及透明化系统状态栏

其实这个也没啥好说的,不管你是android粉还是IOS粉,在日常玩机的过程中,都见过这种界面效果

android 各版本沉浸式 安卓沉浸_状态栏

android 各版本沉浸式 安卓沉浸_android_02

注意图片中的红色部分,相对于传统app的黑色状态栏,这种类型app的布局是一直延伸到状态栏上

2.实现方式

强调一下,“沉浸式”仅仅支持在不低于android4.4的设备上运行,并不向下兼容。并且由于谷歌在android5.0上推出了Material Design,所以4.4跟5+实现方式并不完全一样

  • 第一种需求实现方式

在android5.0以上,官方已经提供了透明化系统状态栏的功能支持,就是将colorPrimary与colorParimaryDark设置成一致就行了

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

但是在android4.4上面,实现方式略有不同,它是在透明模式下使用fitsSystemWindows将contentview移至到状态栏的下方,最后在这个空出来的地方手动添加一层view覆盖上去,达到效果

if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) {
    //将状态栏设置成全透明
    int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
    if ((params.flags & bits)==0) {
        params.flags |= bits;
        //如果是取消全透明,params.flags &= ~bits;
        window.setAttributes(params);
    }
    //设置contentview为fitsSystemWindows
    ViewGroup viewGroup= (ViewGroup) findViewById(android.R.id.content);
    viewGroup.getChildAt(0).setFitsSystemWindows(true);
    //给statusbar着色
    View view=new View(this);
    view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(this)));
    view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
    viewGroup.addView(view);
}
else if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
    window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
}

这段代码应该很好理解

  • 第二种需求实现方式

这把我们先说4.4上如何实现。其实刚才在实现第一种需求的过程中,已经做了状态栏全透明处理,只是不要移位加层并着色即可,这里不多说

android5.0上是将decorview整体变成全屏模式,并且将状态栏设置成全透明即可

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    window.setStatusBarColor(Color.TRANSPARENT);
    findViewById(R.id.toolbar).setBackgroundColor(Color.TRANSPARENT);
}

这样,你的app就已经基本上达到了“沉浸式”的要求,是不是很简单。

3.深坑

我个人开发中写IM的过程中,遇到一个场景:底部edittext要想被软键盘弹起,contentview必须加上fitSystemWindows才能正常。第一种场景倒是没有问题,第二种场景应该怎么做呢?