应用市场上App越来越多的出现沉浸式状态栏的设计(如下图所示)状态栏和导航栏具有相同的颜色。AndroID在4.4开始对于该种效果的支持,而在4.4之下,状态栏只是黑框,无法控制。同时在4.4和5.0及其之上的版本对该种效果的支持又有所差异,因此要实现该种效果,可以将4.4归为一类,5.0及其之上归为一类。接下来,我们将一步步来在4.4和5.0及其之上来实现如下所示效果。
导航栏问题
在AndroID中,顶部导航栏目前常用的两种实现方式,一个是通过Toolbar,一个是通过自定义view的方式来实现。两种方式各有利弊。Toolbar为官方指定规范,开发者使用更方便,但可拓展性差,对于一些特殊的展示效果无法实现,而通过自定义方式的方式,可以支持更多展示效果,但却需要我们写更多的代码。两种方式在实现状态栏沉浸上也有所差别。
去掉Title
Toolbar默认主题会具有一个Title,当我们使用Toolbar的时候,而没有去掉Title,应用则会crash,报出如下所示错误。
因此在使用Toolbar 的时候,我们需要style中添加如下属性配置
<item name="windowNoTitle">true</item>
当然我们也可以通过代码动态去掉Title,但当我们的主题从theme.AppCompat作为父类继承的时候,通过代码并不可以去掉Title。
自定义导航栏
当我们未设置windowNoTitle
属性的时候,在导航栏之上有Title。显然和我们要实现导航栏的沉浸式有所违背,因此实现对于导航栏的沉浸,
<item name="windowNoTitle">true</item>
该配置是必不可少的。
设置状态栏透明
去掉Title之后,是否我们就可以实现上述的效果了呢?
这个时候,我们发现状态栏还是黑色,并没有沉浸,需要我们将状态栏设置为透明。
<item name="androID:windowTranslucentStatus">true</item>
该属性只有在在4.4和高于4.4版本上可以进行该属性的配置,但是在更低版本上则无法使用。配置该属性之后,执行效果如下图所示。
解决导航栏上移问题
这个时候,Toolbar被整体上移了,导致其部分功能也进入了状态栏之下,包括导航栏的内容也到了状态栏位置之中,显然这是不符合我们最初的要求的。如何解决这个问题?我们在Toolbar中添加fitSystemwindows属性,即可使得toolbar的上部空出一个高度,使得Toolbar内容部分脱离状态栏。
<androID.support.v7.Widget.Toolbar androID:ID="@+ID/toolbar" androID:fitsSystemwindows="true" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> </androID.support.v7.Widget.Toolbar>
得到我们最终想要得到的效果
自定义导航栏与之实现类似。
fitsSystemwindows属性
前面对Toolbar的设置是在Toolbar中添加的fitSystemwindows
属性,那么当我们将其属性添加到Toolbar所在的最外层的布局会怎么样呢?
<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" androID:ID="@+ID/activity_toolbar" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:fitsSystemwindows="true"tools:context="com.example.netease.toolbardemo.activity.Toolbaractivity"> <androID.support.v7.Widget.Toolbar androID:ID="@+ID/toolbar" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> </androID.support.v7.Widget.Toolbar></relativeLayout>
执行之后,可以看到和之前未设置状态栏透明时的效果相同。
那么这个fitSystemwindows工作的原理是什么呢?通过上述实验,不难发现,对于沉浸状态栏的控制,该属性起到了一个很关键的作用。
接下来通过一个实验来验证下,该属性所起的作用,在Toolbar所在的布局中,在布局的底部添加一个button.
<androID.support.v7.Widget.Toolbar androID:ID="@+ID/toolbar" androID:fitsSystemwindows="true" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> </androID.support.v7.Widget.Toolbar> <button androID:text="Test" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:background="@color/colorAccent" androID:layout_alignParentBottom="true"/>
当我们将该属性设置到按钮上,又会发生什么呢?
<button androID:text="Test" androID:fitsSystemwindows="true" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:background="@color/colorAccent" androID:layout_alignParentBottom="true"/>
通过比较可以很明显的看出,设置了 fitsSystemwindows
属性的VIEw在其上部被设置了一个padding。根据之前做的实验,我们可以知道当我们设置了窗口状态栏透明之后,整个内容视图会向上移动了一个状态栏的高度,而当前为该VIEw增加的padding的大小是不是和其高度相同呢?
button btn = (button) findVIEwByID(R.ID.test_btn); Log.i("padding",btn.getpaddingtop()+""); Rect frame = new Rect(); getwindow().getDecorVIEw().getwindowVisibledisplayFrame(frame); Log.i("height",frame.top+"");
获取按钮的padding高度和状态栏的高度,我们可以得到如下日志。
通过实验我们可以得出结论, fitSystemwindows
属性会对所设置的VIEw增加一个top padding,因此当我们在实现让导航栏沉浸的时候,设置窗口状态栏的透明会使得视图整体上移,而借助 fitSystemwindows
属性的功能,为视图中最顶部的VIEw设置一个和状态栏高度相同的padding,使得导航栏不会被顶到状态栏内。
当我们在一个视图中,多个VIEw设置该属性时,发现只有第一个设置该属性的VIEw会起作用,在视图布局上,自上而下的第一个VIEw其作用。层级上则为最顶级的VIEw上首先其作用。因此其功能归纳为:
为设置该属性的VIEw增加一个和状态栏高度相同的toppadding 当视图中有多个VIEw被设置了该属性,那么只布局上最顶部的VIEw起作用5.0及其以上
至此,我们可以完美的实现一个状态栏的沉浸,上述的实现是在AndroID 4.4版本上,在视图的最上部,会有一个黑色渐变的阴影,而在5.0设备上的展示效果如下所示,在状态栏上整个都会有一个阴影。当然不同厂家对此也有自己的一些优化,比如魅族在4.4上是不具有阴影的。
对于5.0及其之上,官方提供了对状态栏颜色控制的相应API,我们可以通过代码来控制状态栏的颜色,实现如下效果。
实现代码
if(Build.VERSION.SDK_INT >= 21) { Window window = getwindow(); //取消设置透明状态栏,使 ContentVIEw 内容不再沉浸到状态栏下 window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //需要设置这个 flag 才能调用 setStatusbarcolor 来设置状态栏颜色 window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYstem_bar_BACKGROUNDS); //设置状态栏颜色 window.setStatusbarcolor(getResources().getcolor(R.color.yx_red)); }
据此可以看出,当我们在5.0及其之上的实现中,可以不用进行状态栏透明的设置和 fitSystemwindows
属性的设置,直接通过代码来控制,但为了适应4.4版本,建议在代码中仍然按之前的方式实现,如果想在5.0及其高版本中实现去阴影,再手动在代码中控制。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android沉浸式状态栏实现示例全部内容,希望文章能够帮你解决Android沉浸式状态栏实现示例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)