前言

沉浸式不知道什么时候有了两种叫法,一种是沉浸式模式,一种是沉浸式状态栏,Google从Android4.4开始,给我们开发者提供了一套透明的系统UI样式给状态栏和导航栏,这样完美的玩法简直和IOS系统媲美了。

Part 1、沉浸式模式

    

public void toggle(View view) {int options = getWindow().getDecorView().getSystemUiVisibility();if (Build.VERSION.SDK_INT >= 14) {options ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;//隐藏导航条}if (Build.VERSION.SDK_INT >= 16) {options ^= View.SYSTEM_UI_FLAG_FULLSCREEN;//隐藏系统栏}if (Build.VERSION.SDK_INT >= 19) {//这里有两种沉浸模式//SYSTEM_UI_FLAG_IMMERSIVE_STICKY 你在系统栏区域滑动使得系统栏显示为半透明,// 但是你的flag并没有被清除,监听没有被触发,这个系统栏会自动隐藏//SYSTEM_UI_FLAG_IMMERSIVE 你在系统栏区域滑动使得系统栏显示,将会保持可见的状态options ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;}getWindow().getDecorView().setSystemUiVisibility(options);}

如果你想给单个设置,只需要按照下面的参数进行设置即可

getWindow().getDecorView().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);

Part 2、沉浸式状态栏

在Android5.0+自动实现了沉浸式的效果,状态栏的颜色跟随你在主题中的colorPrimaryDark属性,通过样式进行修改

        <item name="android:statusBarColor">@color/system_bottom_nav_color</item>

在代码中进行设置

        getWindow().setStatusBarColor(getResources().getColor(R.color.material_blue_grey_800));

然而对于沉浸式状态栏要做到兼容的效果着实不易,现在最低兼容到4.4以上,可以在style文件进行设置

        <item name="android:windowTranslucentStatus">true</item>

但这种方法并不推荐使用,兼容性不好,在代码中设置

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

似乎设置起来很简单,但是上面的两种会出现严重的bug,状态栏遮挡住了ToolBar

面对这样的情况我们快速想到的就是加上android:fitsSystemWindows="true",那么在哪层布局加呢?首先我们先来说一下这个属性的含义:设置布局时,是否考虑当前系统窗口的布局,如果为true就会调整整个系统窗口布局(包括状态栏的view)以适应你的布局,不妨我们尝试一下给ToolBar添加android:fitsSystemWindows="true"

效果~

然而ToolBar向上移填充了状态栏部分,这也验证了android:fitsSystemWindows="true"只是让系统窗口布局去适应你设置的控件,针对上面这种效果提供了两种解决方案

1、<推荐>将android:fitsSystemWindows="true"放在最外层的容器,或者你也可以在代码中进行设置

ViewGroup contentView = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);//得到屏幕不包括标题栏的区域View rootView = contentView.getChildAt(0);//得到xml的根布局if(rootView != null && Build.VERSION.SDK_INT >= 14){rootView.setFitsSystemWindows(true);}

效果~

发现给布局最外层容器设置android:fitsSystemWindows="true" 可以达到状态栏透明,并且露出底色---android:windowBackground颜色,这时候需要直接将最外层容器(也可以修改-android:windowBackground颜色)设置成状态栏想要的颜色,下面剩下的布局再包裹一层正常的背景颜色。

效果~

这种解决方案不仅可以解决了状态栏遮挡ToolBar的问题,还解决了ScrollView+EditText存在时ToolBar会被顶出去的问题

效果~

2、针对状态栏遮挡ToolBar的问题还有另外一种解决方案,就是去掉在ToolBar设置的fitsSystemWindows,增加ToolBar的高度并且为ToolBar设置padding,值得注意是此方案也没有解决ScrollView+EditText会将ToolBar推上去的问题

        //1.先设置toolbar的高度ViewGroup.LayoutParams params = mToolbar.getLayoutParams();int statusBarHeight = getStatusBarHeight(this);params.height += statusBarHeight ;mToolbar.setLayoutParams(params );

设置ToolBar的padding

        //2.设置paddingTop,以达到状态栏不遮挡toolbar的内容。mToolbar.setPadding(mToolbar.getPaddingLeft(),mToolbar.getPaddingTop()+getStatusBarHeight(this),mToolbar.getPaddingRight(),mToolbar.getPaddingBottom());

通过查看android.R.dimen.status_bar_height文件知道需要通过反射来得到状态栏的高度

    public int getStatusBarHeight(Context context) {int statusBarHeight = 0;try {Class<?> clazz = Class.forName("com.android.internal.R$dimen");Object obj = clazz.newInstance();Field field = clazz.getField("status_bar_height");int temp = Integer.parseInt(field.get(obj).toString());statusBarHeight = context.getResources().getDimensionPixelSize(temp);} catch (Exception e) {e.printStackTrace();}return statusBarHeight;}

效果~

Part 3、沉浸式虚拟导航栏

在Android5.0+实现底部导航沉浸效果,style实现

<item name="android:navigationBarColor">@color/colorPrimary_pink</item>

代码实现

getWindow().setNavigationBarColor()

在Android4.4可以使用特殊手段让导航栏设置为透明颜色,style实现

<item name="android:windowTranslucentNavigation">true</item>

代码实现

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

效果~

然而虚拟导航栏遮挡了内容,回头想想可能会想到这种情况和上面状态栏遮挡toolbar是一个问题,上面有两种解决方案但对于虚拟导航栏只能使用增加高度设置padding来解决,但是要如何去解决呢,底部的导航栏却不能像ToolBar一样能获得相应的View。这里我们可以做一个假象,让它下面有个设置为和底部虚拟导航栏高度一样的View并设置背景。开始搞~

1、在布局文件底部定义一个View

    <Viewandroid:id="@+id/navigationview"android:layout_width="match_parent"android:layout_height="0dp"android:background="@color/colorPrimary"/>

2、在代码中进行动态的设置

        ViewGroup.LayoutParams pras = mNavigationbar.getLayoutParams();int navigationBarHeight = getNavigationBarHeight(this);pras.height += navigationBarHeight ;mNavigationbar.setLayoutParams(pras);}private int getNavigationBarHeight(Context context) {int navigationbarBarHeight = 0;try {Class<?> clazz = Class.forName("com.android.internal.R$dimen");Object obj = clazz.newInstance();Field field = clazz.getField("navigation_bar_height");int temp = Integer.parseInt(field.get(obj).toString());navigationbarBarHeight = context.getResources().getDimensionPixelSize(temp);} catch (Exception e) {e.printStackTrace();}return navigationbarBarHeight;}

效果~

这样似乎已经解决了导航栏沉浸的效果,但还差点什么,那就是如何判断手机是否有虚拟导航栏或者是否开启了虚拟导航栏,这里说一种常用的思路就是通过判断屏幕的高度-内容的高度>0则存在虚拟导航栏。

 private static boolean hasNavigationBarShow(WindowManager wm){Display display = wm.getDefaultDisplay();DisplayMetrics outMetrics = new DisplayMetrics();//获取整个屏幕的高度display.getRealMetrics(outMetrics);int heightPixels = outMetrics.heightPixels;int widthPixels = outMetrics.widthPixels;//获取内容展示部分的高度outMetrics = new DisplayMetrics();display.getMetrics(outMetrics);int heightPixels2 = outMetrics.heightPixels;int widthPixels2 = outMetrics.widthPixels;int w = widthPixels-widthPixels2;int h = heightPixels-heightPixels2;return  w>0||h>0;//竖屏和横屏两种情况。}

至此,我们就可以写出一套兼容性的沉浸式状态栏导航栏了。

if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT&&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP){if(toolbar!=null){LayoutParams params = toolbar.getLayoutParams();int statusBarHeight = getStatusBarHeight(this);params.height += statusBarHeight ;toolbar.setLayoutParams(params );toolbar.setPadding(toolbar.getPaddingLeft(),toolbar.getPaddingTop()+getStatusBarHeight(this), toolbar.getPaddingRight(),toolbar.getPaddingBottom());toolbar.setBackgroundColor(translucentPrimaryColor);}if(bottomNavigationBar!=null){if(hasNavigationBarShow(getWindowManager())){LayoutParams p = bottomNavigationBar.getLayoutParams();p.height += getNavigationBarHeight(this);bottomNavigationBar.setLayoutParams(p);bottomNavigationBar.setBackgroundColor(translucentPrimaryColor);}}}else if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.LOLLIPOP){getWindow().setNavigationBarColor(translucentPrimaryColor);getWindow().setStatusBarColor(translucentPrimaryColor);}else{//<4.4的,不做处理}

一步两步带你实现Android沉浸式设计相关推荐

  1. 史上最完美的Android沉浸式状态导航栏攻略

    前言 最近我在小破站开发一款新App,叫高能链.我是一个完美主义者,所以不管对架构还是UI,我都是比较抠细节的,在状态栏和导航栏沉浸式这一块,我还是踩了挺多坑,费了挺多精力的.这次我将我踩坑,适配各机 ...

  2. android沉浸式 字体,Android沉浸式状态栏背景色以及字体颜色的修改

    在activity中设置透明状态栏 的思路: 1.让activity的布局全屏 此时布局会和状态栏重叠 2.让布局最上方预留出和状态栏高度一样的高度,将状态栏的背景色设置为透明 效果如下: 一般是在s ...

  3. Android UI进阶之旅9 Material Design之沉浸式设计

    ###沉浸式设计基本概念 官方的沉浸式Translucent定义:就是让整个APP沉浸(充斥了整个屏幕)在屏幕里面,没有显示状态栏,甚至没有显示底部导航栏. 平时大家所讨论的沉浸式:比如QQ的顶部To ...

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

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

  5. 高大上的Android沉浸式状态栏?

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

  6. android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)

    Android沉浸式状态栏(5.0以上系统) 沉浸式状态栏可以分为两种: 1.直接给状态栏设置颜色 (如下图:) 这里写图片描述 java代码形式: if (Build.VERSION.SDK_INT ...

  7. Android 沉浸式模式

    郭霖的专栏 每当你在感叹,如果有这样一个东西就好了的时候,请注意,其实这是你的机会 Android状态栏微技巧,带你真正理解沉浸式模式 目录(?)[+] 什么是沉浸式 隐藏状态栏 隐藏导航栏 真正的沉 ...

  8. Android底部菜单栏、Android沉浸式状态栏(顶部状态栏修改颜色)、自定义标题栏

    0.简介: 没有使用TabHost切换,而是变成FragmentActivity替换Fragment:沉浸式引用的git上面的jar包. 先看图片 1.底部导航栏 核心代码 <span styl ...

  9. android 沉浸式状态栏 19,Android 沉浸式状态栏 以及 伪沉浸式状态栏

    小菜最近在调整页面状态栏的效果,主要包括沉浸式状态栏和伪沉浸状态栏(同事唠嗑给定义的玩的). 前段时间整理过一篇 Android 沉浸式状态栏的多种样式,现在小菜在稍微的补充一下,都是在日常应用中测试 ...

最新文章

  1. 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)
  2. 数据挖掘关联规则挖掘改进算法DHP
  3. Start DWM manually on Windows 7 and vista
  4. C语言预处理命令分类和工作原理
  5. python 公众号菜单_Python脚本--微信公众号自定义菜单的创建及获取
  6. 如何ping通服务器的公网IP?
  7. 解决jQuery与其他库冲突的方法
  8. Spring: 事务传播机制
  9. pythonwin下载中文版_Python官方下载 v3.9.0中文版_Win10镜像官网
  10. Raki的读paper小记:Enhanced Language Representation with Label Knowledge for Span Extraction
  11. gis怎么通过水库划分子流域_分布式水文模型子流域划分方法
  12. Qt 实现画线笔锋效果详细原理
  13. 阿里云短信服务Java实现
  14. MySQL 优化:Explain 执行计划详解
  15. 2022年电工(技师)考试试题模拟考试平台操作
  16. 互联网晚报 | 05月17日 星期二 | 郑州首套房贷利率最低降至4.4%;可口可乐被曝员工不得购买竞品...
  17. BERT!BERT!BERT!
  18. 网易邮箱恢复服务器上删除邮件吗,网易企业邮箱普通邮箱删除邮件找回
  19. 美国硅基和宽禁带半导体供应链竞争力剖析
  20. 2月第二周安全要闻回顾:微软发通缉令 IBM关注犯罪

热门文章

  1. Python代码优化:pyx编译pyd
  2. 岁月,依一抹浅香于心间
  3. 5.临床预测模型的构建--cox回归分析
  4. B2B行业的支付的那些事。
  5. IT经理世界封面报道:淘宝潜规则
  6. 项目起名的一些小单词
  7. java 百万数据查询_java一次性查询几十万,几百万数据解决办法
  8. mysql百万数据建索引时间_mysql百万的数据快速创建索引
  9. Commvault逻辑架构及组件说明
  10. 【项目总结】雪球爬虫完结(附Snowball模块代码)