一步两步带你实现Android沉浸式设计
前言
沉浸式不知道什么时候有了两种叫法,一种是沉浸式模式,一种是沉浸式状态栏,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沉浸式设计相关推荐
- 史上最完美的Android沉浸式状态导航栏攻略
前言 最近我在小破站开发一款新App,叫高能链.我是一个完美主义者,所以不管对架构还是UI,我都是比较抠细节的,在状态栏和导航栏沉浸式这一块,我还是踩了挺多坑,费了挺多精力的.这次我将我踩坑,适配各机 ...
- android沉浸式 字体,Android沉浸式状态栏背景色以及字体颜色的修改
在activity中设置透明状态栏 的思路: 1.让activity的布局全屏 此时布局会和状态栏重叠 2.让布局最上方预留出和状态栏高度一样的高度,将状态栏的背景色设置为透明 效果如下: 一般是在s ...
- Android UI进阶之旅9 Material Design之沉浸式设计
###沉浸式设计基本概念 官方的沉浸式Translucent定义:就是让整个APP沉浸(充斥了整个屏幕)在屏幕里面,没有显示状态栏,甚至没有显示底部导航栏. 平时大家所讨论的沉浸式:比如QQ的顶部To ...
- Android沉浸式模式状态栏(二)
其实说到沉浸式状态栏这个名字,真不知道这种叫法是谁先发起的.因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法.而有些人在没有完全了解清 ...
- 高大上的Android沉浸式状态栏?
背景 之前做过Android沉浸式状态栏的相关需求,但是一直忙于工作,没时间系统的整理下沉浸式相关的知识,所以今天抽出时间,写一篇 Android沉浸式状态栏的文章. 何为沉浸式 沉浸式就是要给用户提 ...
- android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)
Android沉浸式状态栏(5.0以上系统) 沉浸式状态栏可以分为两种: 1.直接给状态栏设置颜色 (如下图:) 这里写图片描述 java代码形式: if (Build.VERSION.SDK_INT ...
- Android 沉浸式模式
郭霖的专栏 每当你在感叹,如果有这样一个东西就好了的时候,请注意,其实这是你的机会 Android状态栏微技巧,带你真正理解沉浸式模式 目录(?)[+] 什么是沉浸式 隐藏状态栏 隐藏导航栏 真正的沉 ...
- Android底部菜单栏、Android沉浸式状态栏(顶部状态栏修改颜色)、自定义标题栏
0.简介: 没有使用TabHost切换,而是变成FragmentActivity替换Fragment:沉浸式引用的git上面的jar包. 先看图片 1.底部导航栏 核心代码 <span styl ...
- android 沉浸式状态栏 19,Android 沉浸式状态栏 以及 伪沉浸式状态栏
小菜最近在调整页面状态栏的效果,主要包括沉浸式状态栏和伪沉浸状态栏(同事唠嗑给定义的玩的). 前段时间整理过一篇 Android 沉浸式状态栏的多种样式,现在小菜在稍微的补充一下,都是在日常应用中测试 ...
最新文章
- 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)
- 数据挖掘关联规则挖掘改进算法DHP
- Start DWM manually on Windows 7 and vista
- C语言预处理命令分类和工作原理
- python 公众号菜单_Python脚本--微信公众号自定义菜单的创建及获取
- 如何ping通服务器的公网IP?
- 解决jQuery与其他库冲突的方法
- Spring: 事务传播机制
- pythonwin下载中文版_Python官方下载 v3.9.0中文版_Win10镜像官网
- Raki的读paper小记:Enhanced Language Representation with Label Knowledge for Span Extraction
- gis怎么通过水库划分子流域_分布式水文模型子流域划分方法
- Qt 实现画线笔锋效果详细原理
- 阿里云短信服务Java实现
- MySQL 优化:Explain 执行计划详解
- 2022年电工(技师)考试试题模拟考试平台操作
- 互联网晚报 | 05月17日 星期二 | 郑州首套房贷利率最低降至4.4%;可口可乐被曝员工不得购买竞品...
- BERT!BERT!BERT!
- 网易邮箱恢复服务器上删除邮件吗,网易企业邮箱普通邮箱删除邮件找回
- 美国硅基和宽禁带半导体供应链竞争力剖析
- 2月第二周安全要闻回顾:微软发通缉令 IBM关注犯罪