Android 沉浸式状态栏的实践

Android 沉浸式状态栏

  • 当我听说沉浸式状态栏的时候我的大脑是空白的。脑袋里想的是 “什么意思”。于是我百度了一下,下面是我总结的一些方法:
  • 第一种是设置主题Theme。
  • 因为 API21 之后(也就是 android 5.0 之后)的状态栏,会默认覆盖一层半透明遮罩。且为了保持4.4以前系统正常使用,故需要三份 style 文件,即默认的values(不设置状态栏透明)、values-v19、values-v21(解决半透明遮罩问题),代码如下:
 <!-- values-v21 -->
    <style name="MyTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
          <!--//设置是否全屏-->
        <!--<item name="android:windowFullscreen">false</item>-->

        <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

 <!-- values-v19。v19 开始有 android:windowTranslucentStatus 这个属性-->
    <style name="MyTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!--//设置是否全屏-->
        <!--<item name="android:windowFullscreen">false</item>-->
    </style>

 <!-- values-->
   <style name="MyTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">       
   </style>
  • 在没有去掉ActionBar时候Android5.0上运行的效果如下,主要想看下状态栏是什么样子,它主要是浅灰色。

这里写图片描述

  • 由上图可以看出,其实布局中的内容已经占用了状态栏,布局中有一个Textview
    内容是HelloWord文字,为了效果明显我们去掉其中的ActionBar,并且给Textview设置高度和背景颜色。如下图

这里写图片描述

  • 很明显,这个TextView延伸到了状态栏,可能在有个情况需要状态这块地方(其实这种情况不存在的),下面我介绍几种解决办法:

    方法一设置fitsSystemWindows属性

  • 当该属性设置 true 时,会在屏幕最上方预留出状态栏高度的 padding。在布局的最外层设置 android:fitsSystemWindows=”true” 属性。当然,也可以通过代码设置:

/**
 * 设置页面最外层布局 FitsSystemWindows 属性
 * @param activity
 * @param value
*/
public static void setFitsSystemWindows(Activity activity, boolean value) {
  ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(android.R.id.content);
  View parentView = contentFrameLayout.getChildAt(0);
  if (parentView != null && Build.VERSION.SDK_INT >= 14) {
      parentView.setFitsSystemWindows(value);
  }
}
  • 效果图如下:

这里写图片描述

通过该设置保留状态栏高度的 paddingTop 后,再设置状态栏的颜色。就可以达到设想的效果。但这种方式实现有些问题,例如我们想设置状态栏为蓝色,再也不能通过在styles.xml配置 如下属性来设置颜色了。

<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>

只能通过设置最外层布局的背景为蓝色来实现,然而一旦设置后,整个布局就都变成了蓝色,只能在下方的布局内容里另外再设置白色背景,而这样就存在过度绘制了。而且设置了 fitsSystemWindows=true 属性的页面,在点击 EditText 调出 软键盘时,整个视图都会被顶上去。如下:

这里写图片描述

方法二 代码添加占位状态栏

核心代码如下
手动给根视图设置一个 paddingTop ,高度为状态栏高度,相当于手动实现了 fitsSystemWindows=true 的效果,然后再在根视图加入一个占位视图,其高度也设置为状态栏高度。

这里写图片描述

效果如下:(左边是虚拟机右边是真机)
这里写图片描述

下图是android6.0的虚拟机效果图,它的导航栏变成了灰色。5.0以上导航栏没有显示成透明。5.0以下起作用。
这里写图片描述

方案二 全屏模式

通过设置 FLAG ,让应用内容占用系统状态栏的空间.

/**
 * 通过设置全屏,设置状态栏透明
 *
 * @param activity
 */
private void fullScreen(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
            Window window = activity.getWindow();
            View decorView = window.getDecorView();
            //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
            int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            decorView.setSystemUiVisibility(option);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            //导航栏颜色也可以正常设置
//                window.setNavigationBarColor(Color.TRANSPARENT);
        } else {
            Window window = activity.getWindow();
            WindowManager.LayoutParams attributes = window.getAttributes();
            int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
            int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
            attributes.flags |= flagTranslucentStatus;
//                attributes.flags |= flagTranslucentNavigation;
            window.setAttributes(attributes);
        }
    }
}

demo下载

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值