概述
前言
Android状态栏透明,状态栏着色与沉浸是我们必须要会弄的东西。 这里告诉你各个版本怎么适配,为什么需要分版本来适配!
怎么使用
状态栏透明:
- 5.0以上:
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
// View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:
//Activity布局全屏显示,但状态栏不会被隐藏覆盖,
//状态栏依然可见,Activity顶端布局部分会被状态遮住。
//SYSTEM_UI_FLAG_LAYOUT_STABLE :
//防止状态栏隐藏,保证你使用fitSystemWindows时候,系统UI边界
//始终不会变,依然存在可见.即使你隐藏了所有,他依然存在,增加了UI稳定性,
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);//状态栏颜色设置为透明。
}
- 4.4到5.0之间
if(Build.VERSION.SDK_INT>=19){
WindowManager.LayoutParams
myLayoutParams = getWindow().getAttributes();
myLayoutParams.flags =(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS|myLayoutParams.flags);
}
//这里大家可能不懂 | 操作因为这里的flags都是只占一位的1的(如000001,000010,000100,001000),其实这里的位或操作就是将FLAG_TRANSLUCENT_STATUS的flags相加起来。详情可看
上面具体位或参数可见这片BLOG分析:
http://blog.csdn.net/luojiusan520/article/details/47696891。
状态栏上色:
- 5.0以上:
官方新加入的API
getWindow().setStatusBarColor(int Color);
//想要什么颜色就用什么颜色,一步到位
- 4.4到5.0之间:
这里由于官方没有给出设置状态栏的颜色API,所以我们需要使用先透明状态栏,然后fitSystemWindows==true,然后填充一个等高的纯色View,来模拟状态栏已经上色了。(fitSystemWindows为true时候,系统UI会占据填充属于他自己的屏幕高度,false时候为使得整个Activity占据屏幕)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
View statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(activity));//获得高和等宽的布局属性
statusBarView.setBackgroundColor(int color);//设置需要的颜色作为背景填充
contentView.addView(statusBarView, lp);
}
}
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;
}//这里参考hongyang的代码
- 状态栏颜色与头布局颜色相同适配(类似QQ)
设置状态栏为透明,让头布局侵入状态栏高度,fitSystemWindows==false默认也为false,设置第一个布局的paddingtop为状态栏高度即可实现这个效果。比如toolbar或者一些自定义的title,(padding为元素边框与元素内容之间的空间距离)
可以看到这里我们设置Textview为头布局,已经侵入状态栏,如果我们设置一个panddingtop就不是OK了!
参考
http://blog.csdn.net/lmj623565791/article/details/48649563/
http://blog.csdn.net/guolin_blog/article/details/51763825
如果看到这一步:相信我们能够完全适配各种需求对于我们的状态栏。但是为什么要分这么多版本来适配呢?这里我分源码 !!15,19,22!!,3个版本来跟进源码查看结果如下
- 各种版本都可以得到getwindow.getdecorview() 得到decorview,(decorview
为最底层界面) 观察这里View.java的最低版本15也支持setsystemUIvisiblity()。但是为什么4.4才能支持透明呢?跟进
4.4以上
/** @param visibility
Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
* {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
* {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
* and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
*/
public void setSystemUiVisibility(int visibility) {
if (visibility != mSystemUiVisibility) {
mSystemUiVisibility = visibility;
if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
mParent.recomputeViewAttributes(this);
}
}
}
4.4以下
/**
* @param visibility
Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
*/
public void setSystemUiVisibility(int visibility) {
if (visibility != mSystemUiVisibility) {
mSystemUiVisibility = visibility;
if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
mParent.recomputeViewAttributes(this);
}
}
}
从这里就可知,这一些SystemUI_flag是4.4之后Android官方才做的适配flags;之前并没有这么多设置沉浸透明相关的系统flag。
- getwinodw().setStatuBarColor()
查看3个版本的window实现的实现类phonewindow内部可得只有API大于21才有明确的API能够设置状态栏颜色。低于5.0不能直接通过API设置颜色。
@Override
public void setStatusBarColor(int color) {
mStatusBarColor = color;
mForcedStatusBarColor = true; //用于判断是否需要上色状态栏。
if (mDecor != null) {
//mDecor也就是Decorview对象。
mDecor.updateColorViews(null, false /* animate */);
}
}
跟进方法
private WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
WindowManager.LayoutParams attrs = getAttributes();
//getAttributes()跟进发现就是 WindowManager.LayoutParams();
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
//首先得到我们布局属性与系统默认的uivisibility,什么不设置的话起初为getWindowSystemUiVisibility()为0。
//
这里就算不是0其实也无所谓。因为systemUiVisibility这一类参数都是只占一位的比如
000001。000010。000100。....进行或操作只能是全部增加,!这里其实也就是回到我们4.4版本设置UI透明可以用来设置参数的条件。
//。。。。。。。
//中间一段代码省略,是判断高低端设备对是否使用硬件图像加速处理什么的,
//。。。。。。。。
updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
mLastTopInset, animate && !disallowAnimate);
//最后传入我们得到的sysUiVisibility 来更改状态栏颜色
//此方法从方法名可知道就是修改颜色的不深究.内部作一些判断颜色是否透明,是否需要隐藏判断,以及具体的颜色处理。
//
//这一个完整的过程也就完成了我们的状态栏修改完成了。
}
最后贴出几个参数的意义
View.SYSTEM_UI_FLAG_VISIBLE :状态栏和Activity共存,Activity不全屏显示。也就是应用平常的显示画面
View.SYSTEM_UI_FLAG_FULLSCREEN :Activity全屏显示,且状态栏被覆盖掉
.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN :Activity全屏显示,但是状态栏不会被覆盖掉,而是正常显示,只是Activity顶端布 局会被覆盖住
View.SYSTEM_UI_FLAG_LAYOUT_STABLE :
防止状态栏隐藏,保证你使用fitSystemWindows时候,系统UI边界
始终不会变,依然存在可见.即使你隐藏了所有,他依然存在,增加了UI稳定性,迫使确认用户了解如何让UI控件回来。
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY:向内滑动的操作会让系统栏临时显示,并处于半透明的状态。此时没有标签会被清除,系统UI可见性监听器也不会被触发。如果用户没有进行操作,系统栏会在一段时间内自动隐藏。
最后
以上就是幸福铃铛为你收集整理的Android状态栏适配源码解析。的全部内容,希望文章能够帮你解决Android状态栏适配源码解析。所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复