之所以提到透明状态栏,是我们通常所需要的给状态栏设置颜色的原理就是这里的透明概念。(Android4.4)API 19
没有提供单独设置“状态栏”颜色的方法
,如果要设置,就需要把View的最上端设置出一定高度的颜色(或者图案),具体高度只要大于等于“状态栏”高度即可,那么已经“透明”了的“状态栏”自然而然就会变成这个颜色(或者图案)。从而达到设置状态栏有颜色的样子。所以可以说是有色状态栏为透明状态栏的一种。因为是以透明状态栏为基础。
但这限于Android5.0以下设置颜色的原理,在5.0之后就提供API可以直接设置颜色了。
四、给状态栏设置颜色
经常会看到这些词:着色状态栏、变色状态栏、单色状态栏
放几张图片,以下就是我们常用状态栏的样式。
大家通常又通常把状态栏和导航栏颜色不一样称作变色状态栏,一样称作单色状态栏、😁、这些名称大家都是自己随意命名的,只要知道是怎么回事就好、说白了就是给
状态栏设置颜色
!
【给状态栏设置颜色】我们要分为两种情况
1.Android4.4以上&&Android5.0以下(API大于等于19小于21)
记得我们上面讲过(Android4.4)API 19没有提供单独设置“状态栏”颜色的方法,如果要设置,就需要把View的最上端设置出一定高度的颜色(或者图案),具体高度只要大于等于“状态栏”高度即可,那么已经“透明”了的“状态栏”自然而然就会变成这个颜色(或者图案)。从而达到设置状态栏有颜色的样子。原理就是4.4提出的透明概念
2.Android5.0以上(API大于等于21)
在5.0我们都知道提出了MaterialDesign的UI设计,导航栏也变成了Toolbar、google默认都会把我们的两栏设置为一深一浅的颜色,你可以说这是变色状态栏,但不是
沉浸
!!我们可以直接通过系统的colorPrimaryDark等颜色值直接修改状态栏的颜色。
或者隐藏状态栏。而隐藏状态栏也分为两种。
沉浸式全屏(我们在前面提到的):比如我们看小说、玩游戏时,在沉浸式全屏状态下,对屏幕的操作并不会唤出系统栏。想要唤出系统栏,你必须从屏幕的上/下边缘向屏幕内划入。
普通全屏:还有一种是类似看视频,通常我们的手指不会碰触屏幕,此时点击屏幕,状态栏就会出现。
重点 :只有4.4以后才可以设置,4.4以下只会显示默认状态栏。
4.4以后之所以可以设置,是因为API新添属性windowTranslucentStatus.
关于设置透明栏我们有两种方式,第一种是通过xml设置,第二种是使用代码设置。推荐代码方式。
通过xml:新建values-v19文件夹,同时新建styles.xml,为activity的Style 添加一个属性,然后在配置文件给相应的activity设置android:theme
<style name="AppTheme" parent="BaseTheme">
<item name="android:windowTranslucentStatus">true</item>
</style>
通过代码设置:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
我们看一下效果
二、有色状态栏
正常标题栏是黑底白字,但有的时候我们的主题背景是浅色,那肯定希望字体颜色为黑色比较好,这时我们需要根据浅色主题做适配,目前可以应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android 。
//有色状态栏,想要和导航栏颜色不一样就设置不一样的颜色即可
public static void setWindowStatusBarColor(Activity activity, int color, boolean isLightMode) {
Log.d("StatusBar", "Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
int statusColor = color;
//如果是浅色主题 可将状态栏图标和文字内容改为黑色样式 实现浅色主题调背景的状态栏效果
//只应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isLightMode) {
int mode = StatusBarLightMode(activity);
//0代表浅色主题没有设置成功
if (mode == 0) {
statusColor = activity.getResources().getColor(R.color.status_bar_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(statusColor);
return;
//4.4以上,5.0以下
//原理:只要在根布局去设置一个与状态栏等高的View,设置背景色为我们期望的颜色就可以
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
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(statusColor);
contentView.addView(statusBarView, lp);
三、全屏模式
1.全屏模式之带状态栏(内容可伸展到状态栏,比如抖音)
页面顶部的图片内容延伸至状态栏中,这种做法其实就是单独使用 <item name="android:windowTranslucentStatus">true</item> 样式,不在 layout 布局文件中添加 android:fitsSystemWindows="true" 属性。
通过设置style方式:
<item name="android:windowTranslucentStatus">true</item>
//如果要取消标题栏
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
//带状态栏的全屏--内容可伸展到状态栏
public static void setFullScreenWithStatusBar(Activity activity){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 设置状态栏透明
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 设置根布局的参数
//将根rootView直接顶上去,和状态栏的顶部对齐。
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
ViewCompat.setFitsSystemWindows(rootView,false);
rootView.setClipToPadding(true);
2.全屏模式之无状态栏
之一:沉浸式状态栏实现
⚠️:切结给状态栏改个颜色不代表就是沉浸!
我们想要的沉浸效果:开启沉浸模式后,状态栏消失,也就是全屏拓展,当从顶部向下滑动,状态栏出现,退出沉浸模式,状态栏也出现了。
因为这个也不是通用的,就没有封装进去,如果有这个需求,参考这篇文章自行设置Android 实现沉浸式状态栏
之二:普通全屏
1.设置style
只是全屏:指定theme为android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
全屏并透明:指定theme为android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
2.或代码实现
//普通全屏
public static void setFullScreenNoStatusBar(Activity activity){
activity.getWindow().
setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
最后放上全部代码
public class StatusBarUtils {
// 使Activity布局填充状态栏
public static void fillStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
View decorView = activity.getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明状态栏
public static void setTranslucentStatusbar(Activity activity) {
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 透明状态栏
//必须要有windowTranslucentStatus这个属性
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 透明导航栏
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
ViewCompat.setFitsSystemWindows(rootView, true);
* @param activity
* @param color
* @param isLightMode
//有色状态栏,想要和导航栏颜色不一样就设置不一样的颜色即可
public static void setWindowStatusBarColor(Activity activity, int color, boolean isLightMode) {
Log.d("StatusBar", "Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
int statusColor = color;
//如果是浅色主题 可将状态栏图标和文字内容改为黑色样式 实现浅色主题调背景的状态栏效果
//只应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isLightMode) {
int mode = StatusBarLightMode(activity);
//0代表浅色主题没有设置成功
if (mode == 0) {
statusColor = activity.getResources().getColor(R.color.status_bar_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(statusColor);
return;
//4.4以上,5.0以下
//原理:只要在根布局去设置一个与状态栏等高的View,设置背景色为我们期望的颜色就可以
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
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(statusColor);
contentView.addView(statusBarView, lp);
//得到系统statusbar的高度
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;
//全屏布局实现方式1
//带状态栏的全屏--内容可伸展到状态栏
public static void setFullScreenWithStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 设置状态栏透明
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 设置根布局的参数
//将根rootView直接顶上去,和状态栏的顶部对齐。
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
ViewCompat.setFitsSystemWindows(rootView, false);
rootView.setClipToPadding(true);
//不带状态栏的全屏
public static void setFullScreenNoStatusBar(Activity activity) {
activity.getWindow().
setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//全屏布局实现方式2
public static void setFullScreen(Activity activity, boolean isHavaStatusBar) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isHavaStatusBar) {
//带状态栏的全屏
activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
} else {
//不带状态栏的全屏
activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
* 设置状态栏黑色字体图标,
* 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
* @param activity
* @return 1:MIUUI 2:Flyme 3:android6.0 0:为没有设置浅色主题成功
public static int StatusBarLightMode(Activity activity) {
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (DeviceUtils.isMiui() && MIUISetStatusBarLightMode(activity.getWindow(), true)) {
result = 1;
//miui android 7.0无法通过反射修改
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 3;
Log.d("statusbar1", "api method");
} else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 3;
return result;
* 设置状态栏图标为深色和魅族特定的文字风格
* 可以用来判断是否为Flyme用户
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
try {
WindowManager.LayoutParams lp = window.getAttributes();
Field darkFlag = WindowManager.LayoutParams.class
.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class
.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
return result;
* 设置状态栏字体图标为深色,需要MIUIV6以上
* @param window 需要设置的窗口
* @param dark 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
Log.d("statusbar1", "miui method: 1");
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
Log.d("statusbar1", "miui method: 2");
result = true;
} catch (Exception e) {
Log.d("statusbar1", "miui method: error");
return result;