361 lines
14 KiB
Java
361 lines
14 KiB
Java
package com.gh.common.util;
|
||
|
||
import android.annotation.SuppressLint;
|
||
import android.app.Activity;
|
||
import android.content.Context;
|
||
import android.content.res.Resources;
|
||
import android.graphics.Color;
|
||
import android.os.Build;
|
||
import android.text.TextUtils;
|
||
import android.util.DisplayMetrics;
|
||
import android.view.Display;
|
||
import android.view.Gravity;
|
||
import android.view.KeyCharacterMap;
|
||
import android.view.KeyEvent;
|
||
import android.view.View;
|
||
import android.view.ViewConfiguration;
|
||
import android.view.ViewGroup;
|
||
import android.view.Window;
|
||
import android.view.WindowManager;
|
||
|
||
import androidx.annotation.ColorInt;
|
||
import androidx.annotation.ColorRes;
|
||
import androidx.core.content.ContextCompat;
|
||
import androidx.core.graphics.ColorUtils;
|
||
|
||
import com.halo.assistant.HaloApp;
|
||
|
||
import java.lang.reflect.Field;
|
||
import java.lang.reflect.Method;
|
||
|
||
public class DisplayUtils {
|
||
|
||
/**
|
||
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
|
||
*/
|
||
public static int dip2px(Context context, float dpValue) {
|
||
final float scale = context.getResources().getDisplayMetrics().density;
|
||
return (int) (dpValue * scale + 0.5f);
|
||
}
|
||
|
||
/**
|
||
* 根据手机的分辨率从 px(像素) 的单位 转成为 dip
|
||
*/
|
||
public static int px2dip(Context context, float pxValue) {
|
||
final float scale = context.getResources().getDisplayMetrics().density;
|
||
return (int) (pxValue / scale + 0.5f);
|
||
}
|
||
|
||
/**
|
||
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
|
||
*/
|
||
public static int dip2px(float dpValue) {
|
||
final float scale = HaloApp.getInstance()
|
||
.getApplication()
|
||
.getResources()
|
||
.getDisplayMetrics().density;
|
||
return (int) (dpValue * scale + 0.5f);
|
||
}
|
||
|
||
|
||
/**
|
||
* 将px值转换为sp值,保证文字大小不变
|
||
*
|
||
* @param pxValue
|
||
* @param pxValue (DisplayMetrics类中属性scaledDensity)
|
||
* @return
|
||
*/
|
||
public static int px2sp(Context context, float pxValue) {
|
||
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
|
||
return (int) (pxValue / fontScale + 0.5f);
|
||
}
|
||
|
||
/**
|
||
* 将sp值转换为px值,保证文字大小不变
|
||
*
|
||
* @param spValue
|
||
* @param spValue (DisplayMetrics类中属性scaledDensity)
|
||
* @return
|
||
*/
|
||
public static int sp2px(Context context, float spValue) {
|
||
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
|
||
return (int) (spValue * fontScale + 0.5f);
|
||
}
|
||
|
||
/**
|
||
* 获取状态栏的高度
|
||
*
|
||
* @param resources 资源
|
||
* @return height
|
||
*/
|
||
public static int getStatusBarHeight(Resources resources) {
|
||
return getInternalDimensionSize(resources, "status_bar_height");
|
||
}
|
||
|
||
public static int getInternalDimensionSize(Resources res, String key) {
|
||
int result = 0;
|
||
int resourceId = res.getIdentifier(key, "dimen", "android");
|
||
if (resourceId > 0) {
|
||
result = res.getDimensionPixelSize(resourceId);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
public static void transparentStatusBar(Activity activity) {
|
||
//make full transparent statusBar
|
||
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
|
||
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
|
||
}
|
||
if (Build.VERSION.SDK_INT >= 19) {
|
||
activity.getWindow()
|
||
.getDecorView()
|
||
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||
}
|
||
if (Build.VERSION.SDK_INT >= 21) {
|
||
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
|
||
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||
}
|
||
}
|
||
|
||
public static void transparentStatusAndNavigation(Activity activity) {
|
||
//make full transparent statusBar
|
||
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
|
||
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
|
||
}
|
||
if (Build.VERSION.SDK_INT >= 19) {
|
||
activity.getWindow()
|
||
.getDecorView()
|
||
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||
}
|
||
if (Build.VERSION.SDK_INT >= 21) {
|
||
setWindowFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
|
||
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||
activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);
|
||
}
|
||
}
|
||
|
||
private static void setWindowFlag(Activity activity, final int bits, boolean on) {
|
||
Window win = activity.getWindow();
|
||
WindowManager.LayoutParams winParams = win.getAttributes();
|
||
if (on) {
|
||
winParams.flags |= bits;
|
||
} else {
|
||
winParams.flags &= ~bits;
|
||
}
|
||
win.setAttributes(winParams);
|
||
}
|
||
|
||
public static void setLightStatusBar(Activity activity, boolean lightStatusBar, boolean isKeepLowVersionMiui) {
|
||
if (!isMiuiOs()) {
|
||
Window window = activity.getWindow();
|
||
View decor = window.getDecorView();
|
||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||
if (lightStatusBar) {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||
} else {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||
}
|
||
} else {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||
}
|
||
} else {
|
||
setMIUIStatusBarStyle(activity, lightStatusBar, isKeepLowVersionMiui);
|
||
}
|
||
}
|
||
|
||
public static void setLightStatusBar(Activity activity, boolean lightStatusBar) {
|
||
setLightStatusBar(activity, lightStatusBar, true);
|
||
}
|
||
|
||
private static void setMIUIStatusBarStyle(Activity activity, boolean lightStatusBar, boolean isKeepLowVersionMiui) {
|
||
Window window = activity.getWindow();
|
||
if (window != null) {
|
||
|
||
View decor = window.getDecorView();
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||
if (lightStatusBar) {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||
} else {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||
}
|
||
} else {
|
||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||
}
|
||
|
||
if (isKeepLowVersionMiui) {
|
||
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);
|
||
extraFlagField.invoke(window, lightStatusBar ? darkModeFlag : 0, darkModeFlag);//状态栏透明且黑色字体
|
||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && lightStatusBar) {
|
||
//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
|
||
activity.getWindow()
|
||
.getDecorView()
|
||
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||
}
|
||
} catch (Exception e) {
|
||
// do nothing
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
public static void setStatusBarColor(Activity activity, int color, boolean lightStatusBar) {
|
||
Window window = activity.getWindow();
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||
if (!isMiuiOs()) {
|
||
//取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
|
||
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||
//需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
|
||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||
}
|
||
|
||
window.setStatusBarColor(ContextCompat.getColor(activity, color));
|
||
}
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||
|
||
setLightStatusBar(activity, lightStatusBar);
|
||
|
||
}
|
||
}
|
||
|
||
public static void setStatusBarColor(Activity activity, @ColorRes int colorRes) {
|
||
Window window = activity.getWindow();
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||
int colorInt = ContextCompat.getColor(activity, colorRes);
|
||
// 设置状态栏底色颜色
|
||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||
window.setStatusBarColor(colorInt);
|
||
// 如果亮色,设置状态栏文字为黑色
|
||
if (isLightColor(colorInt)) {
|
||
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||
} else {
|
||
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static boolean isLightColor(@ColorInt int color) {
|
||
return ColorUtils.calculateLuminance(color) >= 0.5;
|
||
}
|
||
|
||
|
||
private static boolean isMiuiOs() {
|
||
String property = getSystemProperty("ro.miui.ui.version.name", "");
|
||
return !TextUtils.isEmpty(property);
|
||
}
|
||
|
||
private static String getSystemProperty(String key, String defaultValue) {
|
||
try {
|
||
@SuppressLint("PrivateApi") Class<?> clz = Class.forName("android.os.SystemProperties");
|
||
Method method = clz.getMethod("get", String.class, String.class);
|
||
return (String) method.invoke(clz, key, defaultValue);
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
return defaultValue;
|
||
}
|
||
|
||
public static void hideNavigationBar(Activity activity) {
|
||
Window window = activity.getWindow();
|
||
View decorView = window.getDecorView();
|
||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { // lower api
|
||
decorView.setSystemUiVisibility(View.GONE);
|
||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||
decorView.setSystemUiVisibility(uiOptions);
|
||
}
|
||
}
|
||
|
||
public static int retrieveNavigationHeight(Context context) {
|
||
Resources resources = context.getResources();
|
||
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
|
||
return (resourceId > 0 && hasSoftKeys(context)) ? resources.getDimensionPixelSize(resourceId) : 0;
|
||
}
|
||
|
||
//判断导航栏是否显示
|
||
public static boolean isNavigationBarShow(Activity activity) {
|
||
ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView();
|
||
for (int i = 0; i < vp.getChildCount(); i++) {
|
||
View child = vp.getChildAt(i);
|
||
if (child.getId() != -1 && "navigationBarBackground".equals(activity.getResources().getResourceEntryName(child.getId())) && child.getMeasuredHeight() != 0) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public static int getScreenWidth() {
|
||
WindowManager manager = (WindowManager) HaloApp.getInstance().getApplication().getSystemService(Context.WINDOW_SERVICE);
|
||
DisplayMetrics metrics = new DisplayMetrics();
|
||
manager.getDefaultDisplay().getMetrics(metrics);
|
||
return metrics.widthPixels;
|
||
}
|
||
|
||
public static int getScreenHeight() {
|
||
WindowManager manager = (WindowManager) HaloApp.getInstance().getApplication().getSystemService(Context.WINDOW_SERVICE);
|
||
DisplayMetrics metrics = new DisplayMetrics();
|
||
manager.getDefaultDisplay().getMetrics(metrics);
|
||
return metrics.heightPixels;
|
||
}
|
||
|
||
public static int getToastOffset() {
|
||
try {
|
||
int i = Resources.getSystem().getIdentifier("toast_y_offset", "dimen", "android");
|
||
return HaloApp.getInstance().getApplication().getResources().getDimensionPixelSize(i);
|
||
} catch (Resources.NotFoundException e) {
|
||
e.printStackTrace();
|
||
return dip2px(24);
|
||
}
|
||
}
|
||
|
||
public static int getToastDefaultGravity() {
|
||
try {
|
||
int i = Resources.getSystem().getIdentifier("config_toastDefaultGravity", "integer", "android");
|
||
return HaloApp.getInstance().getApplication().getResources().getInteger(i);
|
||
} catch (Resources.NotFoundException e) {
|
||
e.printStackTrace();
|
||
return Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
|
||
}
|
||
}
|
||
|
||
public static boolean hasSoftKeys(Context context) {
|
||
if (!(context instanceof Activity)) return false;
|
||
|
||
boolean hasSoftwareKeys;
|
||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||
Display d = ((Activity) context).getWindowManager().getDefaultDisplay();
|
||
|
||
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
|
||
d.getRealMetrics(realDisplayMetrics);
|
||
|
||
int realHeight = realDisplayMetrics.heightPixels;
|
||
int realWidth = realDisplayMetrics.widthPixels;
|
||
|
||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||
d.getMetrics(displayMetrics);
|
||
|
||
int displayHeight = displayMetrics.heightPixels;
|
||
int displayWidth = displayMetrics.widthPixels;
|
||
|
||
hasSoftwareKeys = realWidth - displayWidth > 0 || realHeight - displayHeight > 0;
|
||
} else {
|
||
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
|
||
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
|
||
hasSoftwareKeys = !hasMenuKey && !hasBackKey;
|
||
}
|
||
return hasSoftwareKeys;
|
||
}
|
||
|
||
}
|