状态栏经历的阶段
android 的状态栏大致经历了以下几个阶段
android 的状态栏大致经历以下几个阶段
- 在android 4.4-android5.0可以实现状态栏的变色,但是效果不是太好,主要实现方式是通过FLAG——TRANSKUCEBT_STATUS这个属性设置状态栏为透明并且为全屏模式,然后通过添加一个StatusBar一样大小的View,将View设置为我们想要的颜色,从而实现状态栏变色。
- 在android 5.0-android6.0系统才真正的支持状态栏变色,系统加入一个重要的属性和方法android:statusBarColor,通过这个属性也可以直接设置状态栏的颜色。
- 在android6.0上主要就是添加一个功能可以修改状态栏上内容和图标的颜色(黑色和白色)
1. android4.4—android5.0
前面已经说过了android4.4—android5.0主要通过FLAG_TRANSLUCENT_STATUS这个属性实现状态栏变色,当使用这个flag时SYSTEM_UI_FLAG_LAYOUT_STABLE和SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN会被自动添加。
- 对于4.4的机型,小米和魅族是透明色,而其它系统上就只是黑色到透明色的渐变。
- 对于5.x的机型,大部分是使背景色半透明,小米和魅族以及其它少数机型会全透明
- 对于6.0以上的机型,设置此flage会使得StatusBar完全透明
- 对于7.0以上的机型,设置此flage会使得StatusBar半透明 属性添加方式: activity.getWindow().addFlags(WindowManager.LayoutManager.LayoutParams.FLAG_TRAVSLUCEBT_STATUS|SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
图片中加了一个textview,可以看到这个textview绘制到了顶部的状态栏中
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
int count = decorView.getChildCount();
//判断是否已经添加了statusBarView
if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) {
decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
} else {
//新建一个和状态栏高宽的view
StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha);
decorView.addView(statusView);
}
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
//rootview不会为状态栏留出状态栏空间
ViewCompat.setFitsSystemWindows(rootView,true);
rootView.setClipToPadding(true);
//
private static StatusBarView createStatusBarView(Activity activity, int color, int alpha) {
// 绘制一个和状态栏一样高的矩形
StatusBarView statusBarView = new StatusBarView(activity);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
statusBarView.setLayoutParams(params);
statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
return statusBarView;
}
android5.0-android.6.0
在开始之前首先看一张图片
上面的颜色都是可以在主题中设置的,如果没有动态的改变他们,则一直遵循这个原则。setStatusBarColor是专门用来设置状态栏的颜色的,但是让这个方法生效,必须给window添加FLAG_GRAWL_SYSTEM_BAR_BACKGROUNDS并且取消FLAG_TRANSLUCENT_STATUS且这个属性会让状态栏透明
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,表明会window负责系统bar的background绘制,绘制透明的系统的bar(状态栏和导航栏),然后用getStatusBarColor()和getNavigationBarColor();的颜色填充相应的区域。
添加方式俩个:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().setStatusBarColor(ContextCompat.getColor(this,android.R.color.holo_blue_dark));
//第二种:在添加到values-21文件中的主题中
<item name="android:windowTranslucentStatus">false</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/holo_blue_dark</item>
android6.0
使用沉浸式的时候会遇到一个问题,那就是Android系统状态栏的字色接近白色或者浅色的时候,状态就看不清了。
这个问题在android6.0可以加个属性SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
为setSystemUiVisibility(int)方法添加的Flag,请求status bar 绘制模式,它可以兼容亮色背景的status bar 。要在设置了FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag ,同时清除了FLAG_TRANSLUCENT_STATUS flag 才会生效。
添加方式同样是两种:
1、在代码中设置:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); }
2、在布局文件中设置(因为是android5.0新添加的属性,所以在添加到values-v23文件夹下的主题中):<item name="android:windowLightStatusBar">true</item>
setSystemUiVisibility
getWindow().getDecorView().setSystemUiVisibility(flag);
- SYSTEM_UI_FLAG_FULLSCREEN(4.1+)
隐藏状态栏,手指在屏幕顶部往下拖动,状态栏会再次出现且不会消失,另外activity界面会重新调整大小,直观感觉就是activity高度有个变小的过程。
- SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN(4.1+):状态栏一直存在并且不会挤压activity高度,状态栏会覆盖在activity之上
- SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN(4.1+):配合SYSTEM_UI_FLAG_FULLSCREEN一起使用,效果使得状态栏出现的时候不会挤压activity高度,状态栏会覆盖在activity之上 -
- SYSTEM_UI_FLAG_HIDE_NAVIGATION(4.0+):会使得虚拟导航栏隐藏,但是由于NavigationBar是非常重要的,因此只要有用户交互(例如点击一个 button),系统就会清除这个flag使NavigationBar就会再次出现,同时activity界面会被挤压 。
- SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION(4.1+):效果使得导航栏不会挤压activity高度,导航栏会覆盖在activity之上。
- SYSTEM_UI_FLAG_IMMERSIVE配合SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用,还记得之前使用SYSTEM_UI_FLAG_HIDE_NAVIGATION之后只要有用户交互,系统就会清除这个flag使NavigationBar就会再次出现,和SYSTEM_UI_FLAG_IMMERSIVE一起使用之后就会使SYSTEM_UI_FLAG_HIDE_NAVIGATION必须手指在屏幕底部往上拖动NavigationBar才会出现
- SYSTEM_UI_FLAG_IMMERSIVE_STICKY配合View.SYSTEM_UI_FLAG_FULLSCREEN和View.SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用,会使状态栏和导航栏以透明的形式出现,并且一段时间后自动消失。 -
- SYSTEM_UI_FLAG_LAYOUT_STABLE:稳定布局,主要是在全屏和非全屏切换时,布局不要有大的变化。一般和View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN、View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION搭配使用