前言

在 Android 4.4 中引入了沉浸模式的功能,但这个版本非真正的沉浸模式,应该说是透明模式。Android 5.0 以后才可以在系统层面实现真正的沉浸式状态栏。
沉浸式状态栏是为了与当前使用的 App 页面风格统一,不会显的那么突兀,保持友好且一致的用户体验而设计,是现在主流 App 必备的适配内容。今天我们就细细的研究一下沉浸式状态栏的适配。

先看效果

实现的功能

  • 真透明状态栏(个别机型无法适配全透明,如锤子)
  • 动态改变 ToolBar 或者自定义的 TitleBar 颜色,修改背景色即可,不需要动态改变状态栏颜色
  • 状态栏主题模式(黑/白色)切换
  • 修复适配 DrawerLayout 在 4.4 上白边的问题
  • 适配“刘海屏”上的沉浸式状态栏
  • 导航栏实现个人认为美观并通配的配色,可自定义修改

看实现代码

状态栏设置为透明

/*** 设置透明StatusBar** @param activity Activity*/
private static void setTranslucentStatusBar(Activity activity) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}Window window = activity.getWindow();//透明状态栏window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0及以上版本,创建 Navigation BarcreateNavBar(activity);} else {//4.4 版本设置为透明状态栏window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}
}

切换状态栏主题

这里主要是为了更好的适配页面背景,因为有的页面适合白色的状态栏图标,有的适合黑色的状态栏图标

/*** Android 6.0使用原始的主题适配** @param activity Activity* @param darkMode 是否是黑色模式*/
public static void setBarDarkMode(Activity activity, boolean darkMode) {Window window = activity.getWindow();if (window == null) {return;}//设置StatusBar模式if (darkMode) {//黑色模式if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//设置statusBar和navigationBar为黑色window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);} else {//设置statusBar为黑色window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}} else {//白色模式int statusBarFlag = View.SYSTEM_UI_FLAG_VISIBLE;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {statusBarFlag = window.getDecorView().getSystemUiVisibility()& ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//设置statusBar为白色,navigationBar为灰色//                int navBarFlag = window.getDecorView().getSystemUiVisibility()//                        & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;//如果想让navigationBar为白色,那么就使用这个代码。int navBarFlag = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;window.getDecorView().setSystemUiVisibility(navBarFlag | statusBarFlag);} else {window.getDecorView().setSystemUiVisibility(statusBarFlag);}}setHuaWeiStatusBar(darkMode, window);
}
白色 黑色

设置 Navigation Bar 配色

现在是全面屏手机了,但是也可以设置开启虚拟导航栏的。这里主要是更改 Navigation Bar 在不同 Android 版本的配色,这里可以根据设计师的配色或者分装成接口使用。

/*** 创建Navigation Bar** @param activity 上下文*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static void createNavBar(Activity activity) {int navBarHeight = getNavigationBarHeight(activity);int navBarWidth = getNavigationBarWidth(activity);if (navBarHeight > 0 && navBarWidth > 0) {//创建NavigationBarView navBar = new View(activity);FrameLayout.LayoutParams pl;if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {pl = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, navBarHeight);pl.gravity = Gravity.BOTTOM;} else {pl = new FrameLayout.LayoutParams(navBarWidth, ViewGroup.LayoutParams.MATCH_PARENT);pl.gravity = Gravity.END;}navBar.setLayoutParams(pl);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {navBar.setBackgroundColor(Color.parseColor("#fffafafa"));} else {navBar.setBackgroundColor(Color.parseColor("#40000000"));}//添加到布局当中ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();decorView.addView(navBar);//设置主布局PaddingBottomViewGroup contentView = decorView.findViewById(android.R.id.content);if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {contentView.setPaddingRelative(0, 0, 0, navBarHeight);} else {contentView.setPaddingRelative(0, 0, navBarWidth, 0);}}
}

修复 DrawerLayout 顶部白边的问题

在实际项目中我们可能会用到 DrawerLayout ,但是设置了透明状态栏后,在 Android 4.4 上会出现顶部白边的问题,通过下面的方法可修复

/*** 设置 DrawerLayout 在4.4版本下透明,不然会出现白边** @param drawerLayout DrawerLayout*/
public static void setTranslucentDrawerLayout(DrawerLayout drawerLayout) {if (drawerLayout != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {drawerLayout.setFitsSystemWindows(true);drawerLayout.setClipToPadding(false);}
}

到这里我们已经看到了实现的核心方法,我已经封装了一个 AndroidBarUtils ,方便项目中使用可以,下面我们介绍一下如何使用,并且你可以直接查看我编写好的 GitHub wiki

使用方法

如何引用?

暂时不提供远程库引用的方式,只有一个类,点击下载 然后放到项目中即可,也方便自己扩展。

调用方法

  • 设置透明状态栏
AndroidBarUtils.setTranslucent(this);
  • 修复重叠问题以及适配“刘海屏”(ToolBar、自定义的TitleBar、NavigationView 都可用)
//ToolBar、自定义的TitleBar 重叠问题以及适配刘海屏
AndroidBarUtils.setBarPaddingTop(this, view);
  • 设置状态栏主题(6.0及以上才有效果)
//false:白色 true:黑色
AndroidBarUtils.setBarDarkMode(this, false);

不常见问题

  • Android 4.4 上使用了 DrawerLayout 会出现白条,如何解决?
AndroidBarUtils.setTranslucentDrawerLayout(drawerLayout);
  • 如何让 NavigationView 适配 刘海屏
AndroidBarUtils.setBarPaddingTop(this,navigationView.getHeaderView(0));

最终效果

源码仓库

  • GitHub 源码,顺手就是一个 Star
  • 体验 Apk 下载

总结

本文我们为了优化用户的 App 使用体验,一起查看了 Android 各个版本上沉浸式(透明)状态栏的实现细节,并适配了黑白状态栏主题以及 DrawerLayoutNavigationView 的异常情况。虽然是很小的一个优化的点,但是从页面美观和体验角度做了很大的提升。

参考:

  • AdvancedImmersiveMode
  • Display Cutouts-Android Developer
  • System UI - Android Developer

关于我

  • 15 年~18 年,使用 Android 原生做智能硬件相关的 App 研发
  • 18 年 5 月,一次偶然的机会接触到了 Flutter ,然后开始自学,可以看 weather_flutter 是我练习 Flutter 的入门实战项目(我现在依然觉得他非常适合 Flutter 入门练习使用)
  • 18 年 8 月,顶着巨大的压力(Flutter 当时还没有 Release 1.0)开始使用 Flutter 开发企业级项目,并且开发维护了十几个 Flutter 插件包(因为当时插件资源非常的匮乏)
  • 截止目前主导并参与上线了 4 款企业级Flutter App,当前正在负责的一款 App 累计用户 120W+,使用 Flutter 得到了极佳的体验

Android 沉浸式(透明)状态栏细研-超级细还附 Demo相关推荐

  1. Android 沉浸式透明状态栏与导航栏

    Android 系统自4.2 开始 UI 上就没多大改变,4.4 也只是增加了透明状态栏与导航栏的功能 这个特性是andorid4.4支持的,最少要api19才可以使用.下面介绍一下使用的方法,非常得 ...

  2. Android UI体验之全屏沉浸式透明状态栏效果

    前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...

  3. android滑动背景变透明,Android右滑退出+沉浸式(透明)状态栏

    背景 上篇文章一个千万量级的APP使用的一些第三方库中,在说到一个使用很广泛的滑动退出库SwipeBackLayout时有提过有时间会分享自己在项目中引入这个库的时候填过的一些坑.前段时间项目加入沉浸 ...

  4. Android实现沉浸式(透明)状态栏适配

    第一种讲解: 在Android系统4.4以前,状态栏的背景色和字体颜色都是不能改变的.但是4.4以后Google增加了改变状态栏背景透明的方法,可以通过两种方式来设置. 直接在Activity中设置W ...

  5. Android沉浸式模式状态栏(二)

    其实说到沉浸式状态栏这个名字,真不知道这种叫法是谁先发起的.因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法.而有些人在没有完全了解清 ...

  6. Android沉浸式状态栏,看完这篇就够了!

    背景 之前做过Android沉浸式状态栏的相关需求,但是一直忙于工作,没时间系统的整理下沉浸式相关的知识,所以今天抽出时间,写一篇 Android沉浸式状态栏的文章. 何为沉浸式 沉浸式就是要给用户提 ...

  7. Android沉浸式状态栏(透明状态栏)最佳实现

    Android沉浸式状态栏(透明状态栏)最佳实现 在Android4.4之前,我们的应用没法改变手机的状态栏颜色,当我们打开应用时,会出现上图中左侧的画面,在屏幕的顶部有一条黑色的状态栏,和应用的风格 ...

  8. Android沉浸式状态栏(透明系统状态栏)

    Android沉浸式状态栏(透明系统状态栏)的目的:顶部系统状态栏和App的导航栏一体化,不给用户突兀的感觉,使用户把更多的视角留在我们的App上. 沉浸式状态栏的兼容情况 Android版本 透明状 ...

  9. Android 沉浸式状态栏 渐变颜色的实现

    Android 沉浸式状态栏 渐变颜色的实现 最近在开发中遇到一种个性化的需求,类似于QQ顶部的渐变状态栏的实现,如下图 首先我们要了解在Android5.0以后,系统API提供直接设置StatusB ...

最新文章

  1. 《Android开发从零开始》——11.AbsoluteLayoutFrameLayout学习
  2. python3的urllib2报错问题解决方法
  3. TCP/IP协议的编写《转载》
  4. android 反调试 方案,Android Native反调试—检测TracerPid值
  5. getServletPath与getRequestURI
  6. 区块链BaaS云服务(40) 泰岳联盟链
  7. [学习笔记]Pollard-Rho
  8. c++访问者模式visitor
  9. 解决:按截图 ctrl+alt+a QQ聊天窗口就自动最小化(QQ以外的可以截图)
  10. CentOS RPM源镜像源(国内+国外)
  11. Git合并最近的commit
  12. 拓端tecdat|R语言多变量广义正交GARCH(GO-GARCH)模型对股市高维波动率时间序列拟合预测
  13. 骑士CMS人才招聘系统初次接触
  14. C++实现简单钢琴(文件读取 - 播放曲谱)
  15. java cobar_Cobar源码解析(二)
  16. 批量插入测试数据的存储过程
  17. 如何将mov格式的视频转换mp4?
  18. 银行存储管理系统oracle,课内资源 - 基于JSP和Oracle实现的志愿服务银行系统
  19. 微信小程序中使用Less
  20. css筋斗云,CSS3 七龙珠筋斗云动画

热门文章

  1. 计算机or笔记本,笔记本or台式机 这几款戴尔主机性能上没得挑
  2. i.MX6ULL终结者电容触摸实验程序设计
  3. iPad 3发布在即,各平板优势大比拼
  4. 深入了解Xcode 7——代码编辑
  5. 蒋宇捷——程序员的进化 - 在拉勾1024程序员节上的演讲
  6. web实现置顶、置底功能、聊天页面、锚点、滚动条、vue、scrollTop、scrollIntoView、scrollHeight
  7. linux设备的uuid,Linux设备中的UUID
  8. 【Captain America Sentinel of Liberty HD】美国队长:自由哨兵 v1.0.2
  9. SQLite源码编译教程
  10. 国内几款接口管理平台,使用体验分析对比:总有一款是你想要的!