Created
December 6, 2019 07:28
-
-
Save bitristan/440cb3077cf223a6104721155cc549dc to your computer and use it in GitHub Desktop.
Android状态栏适配工具类 (https://github.com/Ye-Miao/StatusBarUtil)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.leaf.library; | |
import android.annotation.TargetApi; | |
import android.app.Activity; | |
import android.content.Context; | |
import android.graphics.Color; | |
import android.os.Build; | |
import android.support.annotation.ColorInt; | |
import android.support.annotation.IntRange; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.RequiresApi; | |
import android.util.Log; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.Window; | |
import android.view.WindowManager; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.Method; | |
import java.util.regex.Pattern; | |
/** | |
* @author:created by leaf on 2019-05-07 | |
* Github地址:https://github.com/Ye-Miao | |
* Desc: 状态栏工具类 | |
*/ | |
public class StatusBarUtil { | |
private static final int DEFAULT_ALPHA = 0; | |
/** | |
* 设置状态栏颜色(自定义颜色) | |
* | |
* @param activity 目标activity | |
* @param color 状态栏颜色值 | |
*/ | |
public static void setColor(@NonNull Activity activity, @ColorInt int color) { | |
setColor(activity, color, DEFAULT_ALPHA); | |
} | |
/** | |
* 设置纯色状态栏(自定义颜色,alpha) | |
* | |
* @param activity 目标activity | |
* @param color 状态栏颜色值 | |
* @param alpha 状态栏透明度 | |
*/ | |
public static void setColor(@NonNull Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int alpha) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | |
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); | |
activity.getWindow().setStatusBarColor(cipherColor(color, alpha)); | |
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | |
setTranslucentView((ViewGroup) activity.getWindow().getDecorView(), color, alpha); | |
setRootView(activity, true); | |
} | |
} | |
/** | |
* 设置状态栏渐变颜色 | |
* | |
* @param activity 目标activity | |
* @param view 目标View | |
*/ | |
public static void setGradientColor(@NonNull Activity activity, View view) { | |
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); | |
View fakeStatusBarView = decorView.findViewById(android.R.id.custom); | |
if (fakeStatusBarView != null) { | |
decorView.removeView(fakeStatusBarView); | |
} | |
setRootView(activity, false); | |
setTransparentForWindow(activity); | |
setPaddingTop(activity, view); | |
} | |
/** | |
* 设置透明状态栏 | |
* | |
* @param activity 目标界面 | |
*/ | |
public static void setTransparentForWindow(@NonNull Activity activity) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
activity.getWindow().setStatusBarColor(Color.TRANSPARENT); | |
activity.getWindow() | |
.getDecorView() | |
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); | |
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
activity.getWindow() | |
.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | |
} | |
} | |
/** | |
* 增加View的paddingTop,增加的值为状态栏高度 (智能判断,并设置高度) | |
* | |
* @param context 目标Context | |
* @param view 需要增高的View | |
*/ | |
public static void setPaddingTop(Context context, @NonNull View view) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
ViewGroup.LayoutParams lp = view.getLayoutParams(); | |
if (lp != null && lp.height > 0 && view.getPaddingTop() == 0) { | |
lp.height += getStatusBarHeight(context); | |
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context), | |
view.getPaddingRight(), view.getPaddingBottom()); | |
} | |
} | |
} | |
/** | |
* 设置状态栏darkMode,字体颜色及icon变黑(目前支持MIUI6以上,Flyme4以上,Android M以上) | |
* | |
* @param activity 目标activity | |
*/ | |
public static void setDarkMode(@NonNull Activity activity) { | |
darkMode(activity.getWindow(), true); | |
} | |
/** | |
* 设置状态栏darkMode,字体颜色及icon变亮(目前支持MIUI6以上,Flyme4以上,Android M以上) | |
* | |
* @param activity 目标activity | |
*/ | |
public static void setLightMode(@NonNull Activity activity) { | |
darkMode(activity.getWindow(), false); | |
} | |
@TargetApi(Build.VERSION_CODES.M) | |
private static void darkMode(Window window, boolean dark) { | |
if (isFlyme4()) { | |
setModeForFlyme4(window, dark); | |
} else if (isMIUI6()) { | |
setModeForMIUI6(window, dark); | |
} | |
darkModeForM(window, dark); | |
} | |
/** | |
* android 6.0设置字体颜色 | |
* | |
* @param window 目标window | |
* @param dark 亮色 or 暗色 | |
*/ | |
@RequiresApi(Build.VERSION_CODES.M) | |
private static void darkModeForM(Window window, boolean dark) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
int systemUiVisibility = window.getDecorView().getSystemUiVisibility(); | |
if (dark) { | |
systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; | |
} else { | |
systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; | |
} | |
window.getDecorView().setSystemUiVisibility(systemUiVisibility); | |
} | |
} | |
/** | |
* 设置MIUI6+的状态栏的darkMode,darkMode时候字体颜色及icon | |
* http://dev.xiaomi.com/doc/p=4769/ | |
* | |
* @param window 目标window | |
* @param dark 亮色 or 暗色 | |
*/ | |
private static void setModeForMIUI6(Window window, boolean dark) { | |
Class<? extends Window> clazz = window.getClass(); | |
try { | |
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); | |
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); | |
int darkModeFlag = field.getInt(layoutParams); | |
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); | |
extraFlagField.invoke(window, dark ? darkModeFlag : 0, darkModeFlag); | |
} catch (Exception e) { | |
Log.e("StatusBar", "darkIcon: failed"); | |
} | |
} | |
/** | |
* 设置Flyme4+的状态栏的darkMode,darkMode时候字体颜色及icon | |
* http://open-wiki.flyme.cn/index.php?title=Flyme%E7%B3%BB%E7%BB%9FAPI | |
* | |
* @param window 目标window | |
* @param dark 亮色 or 暗色 | |
*/ | |
private static void setModeForFlyme4(Window window, boolean dark) { | |
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); | |
} catch (Exception e) { | |
Log.e("StatusBar", "darkIcon: failed"); | |
} | |
} | |
/** | |
* 判断是否Flyme4以上 | |
*/ | |
private static boolean isFlyme4() { | |
return Build.FINGERPRINT.contains("Flyme_OS_4") || Build.VERSION.INCREMENTAL.contains("Flyme_OS_4") | |
|| Pattern.compile("Flyme OS [4|5]", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find(); | |
} | |
/** | |
* 判断是否MIUI6以上 | |
*/ | |
private static boolean isMIUI6() { | |
try { | |
Class<?> clz = Class.forName("android.os.SystemProperties"); | |
Method mtd = clz.getMethod("get", String.class); | |
String val = (String) mtd.invoke(null, "ro.miui.ui.version.name"); | |
val = val.replaceAll("[vV]", ""); | |
int version = Integer.parseInt(val); | |
return version >= 6; | |
} catch (Exception e) { | |
return false; | |
} | |
} | |
/** | |
* 计算alpha色值 | |
* | |
* @param color 状态栏颜色值 | |
* @param alpha 状态栏透明度 | |
*/ | |
private static int cipherColor(@ColorInt int color, int alpha) { | |
if (alpha == 0) { | |
return color; | |
} | |
float a = 1 - alpha / 255f; | |
int red = color >> 16 & 0xff; | |
int green = color >> 8 & 0xff; | |
int blue = color & 0xff; | |
red = (int) (red * a + 0.5); | |
green = (int) (green * a + 0.5); | |
blue = (int) (blue * a + 0.5); | |
return 0xff << 24 | red << 16 | green << 8 | blue; | |
} | |
/** | |
* 创建透明View | |
* | |
* @param viewGroup 目标视图 | |
* @param color 状态栏颜色值 | |
* @param alpha 状态栏透明度 | |
*/ | |
private static void setTranslucentView(ViewGroup viewGroup, @ColorInt int color, @IntRange(from = 0, to = 255) int alpha) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
int cipherColor = cipherColor(color, alpha); | |
View translucentView = viewGroup.findViewById(android.R.id.custom); | |
if (translucentView == null && cipherColor != 0) { | |
translucentView = new View(viewGroup.getContext()); | |
translucentView.setId(android.R.id.custom); | |
ViewGroup.LayoutParams params = | |
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(viewGroup.getContext())); | |
viewGroup.addView(translucentView, params); | |
} | |
if (translucentView != null) { | |
translucentView.setBackgroundColor(cipherColor); | |
} | |
} | |
} | |
/** | |
* 设置根布局参数 | |
* | |
* @param activity 目标activity | |
* @param fitSystemWindows 是否预留toolbar的高度 | |
*/ | |
private static void setRootView(Activity activity, boolean fitSystemWindows) { | |
ViewGroup parent = activity.findViewById(android.R.id.content); | |
for (int i = 0, count = parent.getChildCount(); i < count; i++) { | |
View childView = parent.getChildAt(i); | |
if (childView instanceof ViewGroup) { | |
childView.setFitsSystemWindows(fitSystemWindows); | |
((ViewGroup) childView).setClipToPadding(fitSystemWindows); | |
} | |
} | |
} | |
/** | |
* 获取状态栏高度 | |
* | |
* @param context 目标Context | |
*/ | |
private static int getStatusBarHeight(Context context) { | |
// 获得状态栏高度 | |
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); | |
return context.getResources().getDimensionPixelSize(resourceId); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment