上代码
/**
* Created by Android Studio.
* ProjectName: ----
* Author: HongYu ()
* Create date: by Baron on 2020/12/1 10:42 AM
* Last modified by YanTao ()
* Last modified date: by Baron on 2020/12/1 10:42 AM
* \ --------------------------------------------
* \| The only thing that is constant is change! |
* \ --------------------------------------------
* \ \
* \ \ \_\_ _/_/
* \ \ \__/
* \ (oo)\_______
* \ (__)\ )\/\
* \ ||----w |
* \ || ||
*/
public class StatusBarUtils {
private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.fake_status_bar_view;
public static int getHeight(Context context) {
int statusBarHeight = 0;
try {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
"android");
if (resourceId > 0) {
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
} catch (Exception e) {
e.printStackTrace();
}
return statusBarHeight;
}
/// Android 5.0+ /开始
//设置状态栏颜色的功能:
public static void setColor(@NonNull Window window, @ColorInt int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.setStatusBarColor(color);
//设置沉浸式的颜色(避免北京颜色太亮出现看不清沉浸式的情况)但是官方仅在Android 6.0以上版本提供支持
setTextDark(window, !isDarkColor(color));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//设置状态栏颜色
//在设置纯颜色时,我们还需要将该颜色与黑色进行1:1的混合。为什么要这么设置呢?
// 因为状态栏的文字和图标颜色默认是白色的,并且在Android 5.0以下是不能修改的,所以如果修改成较浅的颜色,
// 就会导致状态栏文字看不清的现象,因此做一个比较暗的浮层效果更好一些。
setColor(window, ColorUtils.blendARGB(Color.TRANSPARENT, color, 0.5f), false);
}
}
//为了便于对Activity直接操作,可以再增加一个如下方法:
public static void setColor(Context context, @ColorInt int color) {
if (context instanceof Activity) {
setColor(((Activity) context).getWindow(), color);
}
}
private static void setTextDark(Window window, boolean isDark) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
View decorView = window.getDecorView();
int systemUiVisibility = decorView.getSystemUiVisibility();
if (isDark) {
decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decorView.setSystemUiVisibility(systemUiVisibility & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
}
public static void setTextDark(Context context, boolean isDark) {
if (context instanceof Activity) {
setTextDark(((Activity) context).getWindow(), isDark);
}
}
//为了防止背景颜色太亮所以需要进行判断是否是深色与亮色(只适配6.0以上的手机)
public static boolean isDarkColor(@ColorInt int color) {
return ColorUtils.calculateLuminance(color) < 0.5;
}
//那么6.0一下的手机怎么办呢来了
//目前Android 5.0-6.0的手机只有小米MIUI和魅族Flyme系统提供了支持。小米MIUI的设置方法如下:
private static void setMIUIDark(Window window, boolean isDark) {//小米
try {
Class<? extends Window> clazz = window.getClass();
int darkModeFlag;
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);
extraFlagField.invoke(window, isDark ? darkModeFlag : 0, darkModeFlag);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setFlymeDark(Window window, boolean isDark) {//魅族
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 (isDark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static boolean isMIUI() {
String manufacturer = Build.MANUFACTURER;
//这个字符串可以自己定义,例如判断华为就填写huawei,魅族就填写meizu
if ("xiaomi".equalsIgnoreCase(manufacturer)) {
return true;
}
return false;
}
//设置状态栏透明(可以设置图片)
public static void setTransparent(@NonNull Window window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//android 4.0修改状态栏透明
setColor(window, 0x80000000, true);
}
}
//同样针对Activity,增加如下方法:
public static void setTransparent(Context context) {
if (context instanceof Activity) {
setTransparent(((Activity) context).getWindow());
}
}
/// Android 4.4+ /
// 下面针对Android 4.4-5.0的手机进行实现。实现原理是将内容布局设为全屏,然后在布局的顶部添加一个
// 和状态栏一样高度的View,将该View的背景设置成我们想要的颜色。当需要将状态栏设置纯颜色时
// ,为了和Android 5.0以上版本保持一致,我们对内容布局的上边设置一个padding,大小为状态栏的高度。
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static void setColor(@NonNull Window window, @ColorInt int color,
boolean isTransparent) {
Context context = window.getContext();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
ViewGroup decorView = (ViewGroup) window.getDecorView();
View contentView = decorView.findViewById(android.R.id.content);
if (contentView != null) {
contentView.setPadding(0, isTransparent ? 0 : getHeight(context), 0, 0);
}
View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
fakeStatusBarView.setBackgroundColor(color);
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
} else {
// 绘制一个和状态栏一样高的矩形
View statusBarView = new View(context);
FrameLayout.LayoutParams layoutParams =
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getHeight(context));
statusBarView.setLayoutParams(layoutParams);
statusBarView.setBackgroundColor(color);
statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
decorView.addView(statusBarView);
}
}
/// 特殊场景 /现在来针对一些特殊场景进行适配,比如启动页、刘海屏和弹窗等等。
//其实Android P已经出可以适配刘海屏幕的代码两将下面代码放到MainActivity的onreate里面
/* // 适配刘海屏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(layoutParams);
}*/
//但是一些手机厂商的刘海屏手机系统版本是低于Android P的,
// 不过也都提供了适配的方法。适配方式是在AndroidManifest.xml文件里的application标签下添加如下代码:
/* <!-- 允许绘制到小米刘海屏机型的刘海区域 -->
<meta-data
android:name="notch.config"
android:value="portrait" />
<!-- 允许绘制到华为刘海屏机型的刘海区域 -->
<meta-data
android:name="android.notch_support"
android:value="true" />
<!-- 允许绘制到oppo、vivo刘海屏机型的刘海区域 -->
<meta-data
android:name="android.max_aspect"
android:value="2.2" />*/
//另外,对于Android 5.0以下的手机,适配完刘海屏后会在顶部多一块黑色半透明的View,那我们将其改成全透明的,修改onCreate()方法如下:
/*@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
StatusBarUtils.setTransparent(this);
// 适配刘海屏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(layoutParams);
}
// 适配Android 4.4
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
StatusBarUtils.setColor(getWindow(), Color.TRANSPARENT, true);
}
}*/
}
使用方法
StatusBarUtils.setColor(this, getResources().getColor(R.color.colorAccent));
StatusBarUtils.setTransparent(this);