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; } }