实现Android K的伪沉浸式
在Android 5.0之后引入了MD风格,从而状态栏沉浸也成为了一种设计习惯。而停留在之Android L之前的Android系统则不能直接实现沉浸式,这里就介绍一下如何实现Android K系列的伪沉浸式。
关于沉浸式效果,这里随便贴几张图吧

Android L效果图

Android 4.2效果图
可以看出在Android K系列中,状态栏是渐变的效果
下面开始讲解如何实现上图的效果,在此就不赘述Android L或以上的沉浸式的效果实现了,在xml上配置几个属性就可以了
题外话:这篇文章介绍的都是使用Android Studio作为IDE开发Android的,如果使用的是其他IDE应按照相关设置进行设置或者配置xml等文件。
开始学习伪沉浸式
所谓的其他知识,就是创建一个其他App中的Activity共有的基类BaseActivity,让其继承AppCompatActivity,然后在基类中实现伪沉浸式,这样Acticity就能专注于自己的内容,而把这些共有的设置交给BaseActivity处理。
现在看看这部分如何处理,先看代码:
public class BaseActivity extends AppCompatActivity {
private int mColor = -1;
public BaseActivity(){
}
public BaseActivity(int color){
super();
mColor = color;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState );
StatusBarCompat.compat(this, ContextCompat.getColor(this, mColor));
}
public static class StatusBarCompat{
private static final int INVALID_VAL = -1;
private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
public static void compat(Activity activity, int statusColor){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if(statusColor != INVALID_VAL){
activity.getWindow().setStatusBarColor(statusColor);
}
return;
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
int color = COLOR_DEFAULT;
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
if(statusColor != INVALID_VAL){
color = statusColor;
}
View statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(activity));
statusBarView.setBackgroundColor(color);
contentView.addView(statusBarView, lp);
//contentView.addView(statusBarView, 0, lp);
}
}
public static void compat(Activity activity){
compat(activity, INVALID_VAL);
}
public static int getStatusBarHeight(Context context){
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height",
"dimen", "android");
if(resourceId > 0){
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
}
跟着步骤,没必要全部看那些凌乱的代码,在这里讲解重点部分,在BaseActivity中提供了一个单一参数的构造函数,目的是让子类选择伪沉浸的颜色,在onCreate函数中调用了StatusBarCompat.compat(this, ContextCompat.getColor(this, mColor))函数,StatusBarCompat是其内部类,我们看看compat函数是如何实现伪沉浸的。
第一个if是判断系统如果为Android L或以上的系统则直接调用setStatusBarColor函数,这是API 21之后提供设置状态栏颜色的函数,然后是第三个if用于判断是否为Android K系统,如果是则开始我们的步骤。里面的内容其实是这样的,我们在XML里配置好状态栏的背景为透明,然后在我们的布局中插入一个和状态栏等高的View,从而在视觉上看起来就是沉浸式的效果了。从字面上很容易理解这样做的意义,然后简单分析一下可行性。首先,如何获取我们的布局,方法很多,可以给根布局设置一个id,然后Activity.findViewById直接获取根布局。其实在这里也可以不获取布局,可以在xml中设置一个View,然后在这里获取这个View并且设置它的高度为状态栏的高度,背景为Activity中传过来的颜色即可。这里就不介绍这两种方法,介绍一种获取我们根布局的其他方法。代码35行findViewById(android.R.id.content)获取了一个FrameLayout,然后奇怪了,为什么是获取一个FrameLayout呢,其实是这样的,我们的布局都是设置在AppCompatActivity的FrameLayout布局中的,这段代码就是为了获取这个ViewGroup的内容的,因此,现在我们手中就掌握了整个Activity的ViewGroup,我们的操作就在这里进行。获取了真正的根布局,当然是开始创建一个View,然后让其高度和状态栏高度一致,然后再设置到刚刚获取的ViewGroup中去就可以了。其中getStatusBarHeight就是获取系统状态栏高度的函数,然后设置View的背景色,然后add到ViewGroup就完成了整个操作。现在工作还没完成呢,既然是Android K的机子,先配置XML吧,在res目录下新建一个values-v19的文件夹,然后新建styles.xml文件,贴上以下代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@style/BaseAppTheme">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
顺便看看BaseAppTheme的代码,这部分代码在res/values/styles里面:
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
其中android:windowTranslucentStatus属性设置的是状态栏是否设置为透明状态,这个是v19之后才引入的属性。
到这里,看似好像完成了,但问题还没完全解决,那就是ToolBar的空间位置问题,假如不处理,如图:

看出效果是ToolBar和状态栏挤成了一块,但这不是这篇文章中所想要的效果,那应该怎么办呢?其实只需设置ToolBar的一个属性android:fitsSystemWindows="true"即可。该属性的意义就是让当前设置这个属性的view设置对应的padding为状态栏腾出对应的空间,说白了就好像是paddingTop=statusBarHeight。
按步骤设置好之后,还有一步,不然看到的是代码里面默认设置的颜色,所以要在Activity中传递color给BaseActivity,简单的代码如下:
public MainActivity(){
this(R.color.colorPrimary);
3 }
private MainActivity(int color){
super(color);
}
只需修改R.color.colorPrimary为自己需要的颜色即可。为什么需要这样操作,很简单,因为默认启动调用的是无参构造函数,所以让无参去调用有参构造,即可实现,这也解释了为什么父类要去定义这个有参构造了。
运行了一下效果,嗯,还不错,但当你如果用的是这个方法添加的view作状态栏背景色的话,其实有一个坑,不过我贴的代码上已经解释了这个坑的处理方法了。这个坑其实就是和DrawerLayout配合使用的时候,当你打开抽屉的时候,会看到侧滑菜单在状态栏的下面,如图所示:

可以看到,状态栏把侧滑菜单挡住了,说白了其实是我们添加的view把状态栏挡住了。如何解决呢,在上面代码中注释了一句,其实使用下面那个三参数的函数就可以解决这个问题了,如图:

可以看出,侧滑菜单已经覆盖在充当状态栏背景的那个view上面了。为什么会这样呢,理由很简单,使用第一个函数的时候它是直接add到FrameLayout最上面的,所以就挡在了我们的布局上面,而addView(statusBar, 0, lp)的意思则是插入到第1个View的位置,因此就会让它插入到我们的布局下面,因此就实现了我们所想要的效果。既然两个参数有先后问题,那我们是否可以在Activity的onCreat函数中这样操作呢,比如先super.onCreat然后再调用setContentView,看似这样子我们的布局就应该在充当状态栏背景的view上面了,其实这是一个坑,我们在onCreat中必须是先调用setContentView然后再调用基类的onCreat,否则,状态栏的效果如图:

其实,从setContentView的名字可以看出来为什么了,既然这个是设置自定义布局,显然,调用这个函数的时候会将FrameLayout里面的内容清空,因此后调用这个函数的时候,之前add进去的view已经被清空了。
到这里,关于Android K的伪沉浸式效果就实现了。
实现Android K的伪沉浸式的更多相关文章
- Android状态栏透明(沉浸式效果)
Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487880 ...
- android 三步实现沉浸式 简单到无法想象
今天产品来看进度,说ios状态栏可以改颜色,以前竟然也没注意过,看了美团 ,扣扣的实现, 才注意到.着手开始做.网上借鉴了点 ,各种乱,整理了下 .希望可以帮到大家 . [转载请标明出处] 前提: ...
- Android隐藏状态栏实现沉浸式体验
转自: Android状态栏微技巧,带你真正理解沉浸式模式 什么叫沉浸式? 根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉. 那么对应到Android ...
- Android KITKAT 以上实现沉浸式状态栏
extends:http://www.jianshu.com/p/f8374d6267ef 代码未行,效果先上 Flyme4.2 Android4.4.4上运行效果 如何实现 在 KITKAT 之后, ...
- Android QMUI实战:沉浸式/适配状态栏
近期研究QMUI换肤的实现,顺便分析了下QMUI的沉浸式. 网上已有很多关于QMUI实现页面沉浸式的文章,简而言之:复杂了. 本期,我们仅通过几行代码,即可完美实现页面沉浸式效果,并轻松匹配换肤的色彩 ...
- android全屏/沉浸式状态栏下,各种键盘挡住输入框解决办法
https://blog.csdn.net/smileiam/article/details/69055963
- Android沉浸式状态栏实现
Step1:状态栏与导航栏半透明化 方法一:继承主题特定主题 在Android API 19以上可以使用****.TranslucentDecor***有关的主题,自带相应半透明效果 例如: < ...
- android -------- 沉浸式状态栏和沉浸式导航栏(ImmersionBar)
android 4.4以上沉浸式状态栏和沉浸式导航栏管理,包括状态栏字体颜色,适用于Activity.Fragment.DialogFragment.Dialog,并且适配刘海屏,适配软键盘弹出等问题 ...
- Android 沉浸式状态栏的三种实现方式
沉浸式状态栏 Google从android kitkat(Android 4.4)開始,给我们开发人员提供了一套能透明的系统ui样式给状态栏和导航栏,这种话就不用向曾经那样每天面对着黑乎乎的上下两条黑 ...
随机推荐
- 使用lombok
Lombok是一种JavaArchive(JAR)文件,可用来消除Java代码的冗长.通过在开发环境中实现Lombok,开发人 员可以节省构建诸如hashCode()和equals()这样的方法以及以 ...
- activiti入门2流程引擎的API和服务基础
RepositoryService : 管理和控制发布包和流程定义(包含了一个流程每个环节的结构和行为)的操作 除此之外,服务可以 查询引擎中的发布包和流程定义. 暂停或激活发布包,对应全部和特定 ...
- HashMap大小选择
java hashmap,如果确定只装载100个元素,new HashMap(?)多少是最佳的,why? 要回答这个问题,首先得知道影响HashMap性能的参数有哪些.咱们翻翻JDK. 在JDK6中是 ...
- semijoin链接进行subquery unnesting.
drop table emp1; drop table dept1; create table emp1 as select * from emp; create table dept1 as sel ...
- C++ Prime:预处理器
C++程序会用到的一项预处理功能是头文件保护符,头文件保护符依赖于预处理变量.预处理变量有两种状态:已定义和未定义,#define指令把一个名字设定为预处理变量,另外两个指令则分别检查某个指定的预处理 ...
- (转)ASP.NET MVC路由配置
一.命名参数规范+匿名对象 1 routes.MapRoute(name: "Default", 2 url: "{controller}/{action}/{id}&q ...
- 模糊化GPU滤镜汇总
GPUImageTiltShiftFilter 这是一个模糊图片上下两层的滤镜效果,可以调节模糊边界,可以调节模糊程度 总共4个参数,具体如下 //模糊度的调节,0为最清晰,后面越来越模糊 ...
- 以O2O为核心的ERP思考
O2O已经火了一阵子了,很多人都在说O2O,各行各业都想和O2O有所结合,都认为这里面将会有巨大的商机. 在互联网发展到移动互联网的时代,我们的生活的很多方面已经被改变了,很多事情都已经可以在移动端完 ...
- 细谈Java
重载:相同函数名,不同参数. 重写(覆写):父类和子类之间的,子类重写了父类的方法. java的多态:重载+覆写 1. Main方法: 是public的,也是static,也是void的,参 ...
- Spring3 M2 quartz-2.1.7 解决bean不能注入问题
我们要达到这样的效果 public class CancelUnpaidOrderTask implements Job { @Autowired private AppOrderService or ...