package com.example.basecore.util;
|
|
import android.annotation.TargetApi;
|
import android.app.Activity;
|
import android.app.Dialog;
|
import android.content.Context;
|
import android.content.res.Resources;
|
import android.graphics.Point;
|
import android.graphics.Rect;
|
import android.graphics.RectF;
|
import android.os.Build;
|
import android.provider.Settings;
|
import android.util.DisplayMetrics;
|
import android.view.Display;
|
import android.view.View;
|
import android.view.ViewGroup;
|
import android.view.Window;
|
import android.view.WindowManager;
|
|
|
import static android.content.Context.WINDOW_SERVICE;
|
import static androidx.recyclerview.widget.RecyclerView.NO_ID;
|
|
import androidx.annotation.NonNull;
|
|
|
public class ScreenUtil {
|
|
private static final String NAVIGATION = "navigationBarBackground";
|
|
public static int getScreenWidth(Context context) {
|
return ScreenUtils.getAppDisplayWidth(context);
|
}
|
|
public static int getScreenHeight(Context context) {
|
return ScreenUtils.getDeviceScreenHeight(context);
|
}
|
|
public static int getScreenHeightNoNav(Context context) {
|
return getScreenHeight(context) - getBottomNavBarHeight(context);
|
}
|
|
/**
|
* 需要传递 application的 context ,能够适配更多手机
|
* @param context application
|
* @return 不包含导航栏的高度
|
*/
|
public static int getCompatScreenHeightNoNav(Context context){
|
int screenHeight = getScreenHeight(context);
|
if (hasNavigationBar(context)) {
|
screenHeight -= getNavigationBarHeight(context);
|
}
|
return screenHeight;
|
}
|
|
|
public static double getScreenInches(Context context) {
|
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
int width = dm.widthPixels;
|
int height = dm.heightPixels;
|
double wi = (double) width / (double) dm.xdpi;
|
double hi = (double) height / (double) dm.ydpi;
|
double x = Math.pow(wi, 2);
|
double y = Math.pow(hi, 2);
|
double screenInches = Math.sqrt(x + y);
|
return screenInches;
|
}
|
|
public static double getScreenWidthInches(Context context) {
|
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
int width = dm.widthPixels;
|
double wi = (double) width / (double) dm.xdpi;
|
return wi;
|
}
|
|
public static double getScreenHeightInches(Context context) {
|
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
int height = dm.heightPixels;
|
double hi = (double) height / (double) dm.ydpi;
|
return hi;
|
}
|
|
public static RectF getGlobalVisibleRect(View view) {
|
if (null != view) {
|
Rect rect = new Rect();
|
view.getGlobalVisibleRect(rect);
|
return new RectF(rect);
|
}
|
return null;
|
}
|
|
public static RectF getGlobalRect(View view) {
|
if (null != view) {
|
RectF rect = new RectF();
|
View currentView = view;
|
// currentView.getLocalVisibleRect(rect); //这种方式无法获取屏幕外部区域值
|
int[] xy = new int[2];
|
currentView.getLocationInWindow(xy);
|
float width = currentView.getScaleX() * currentView.getWidth();
|
float height = currentView.getScaleY() * currentView.getHeight();
|
rect.set(xy[0], xy[1], xy[0] + width, xy[1] + height);
|
return rect;
|
}
|
return null;
|
}
|
|
private static boolean hasNavBar(Context context) {
|
WindowManager wm = (WindowManager) context
|
.getSystemService(WINDOW_SERVICE);
|
if (wm != null) {
|
Display display = wm.getDefaultDisplay();
|
Point size = new Point();
|
Point realSize = new Point();
|
display.getSize(size);
|
display.getRealSize(realSize);
|
return realSize.y != size.y;
|
} else {
|
return true;
|
}
|
}
|
|
public static boolean hasNavBar2(Activity activity) {
|
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
int count = decorView.getChildCount();
|
for (int i = 0; i < count; i++) {
|
View view = decorView.getChildAt(i);
|
if (view.getId() != NO_ID &&
|
NAVIGATION.equals(activity.getResources().getResourceEntryName(view.getId()))
|
&& view.getVisibility() == View.VISIBLE) {
|
return true;
|
}
|
|
}
|
return false;
|
}
|
|
private static boolean xiaomiHasNavBar(Context context) {
|
return Settings.Global.getInt(context.getContentResolver(), "force_fsg_nav_bar", 0) != 0;
|
}
|
|
public static int getBottomNavBarHeight(Context context) {
|
if (!hasNavBar(context)) {
|
return 0;
|
}
|
if (context instanceof Activity) {
|
if (!hasNavBar2((Activity) context)) {
|
return 0;
|
}
|
}
|
Resources resources = context.getResources();
|
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
|
if (resourceId > 0) {
|
return resources.getDimensionPixelSize(resourceId);
|
}
|
return 0;
|
}
|
|
public static int getTopNavBarHeight(Context context) {
|
Resources resources = context.getResources();
|
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
|
if (resourceId > 0) {
|
return resources.getDimensionPixelSize(resourceId);
|
}
|
return 0;
|
}
|
|
/**
|
* 判断当前view是否出现在可视窗口
|
*
|
* @param view 视图
|
* @param forceInside 是否所有区域都在出现在屏幕内
|
* @return
|
*/
|
public static boolean isViewInScreen(View view, boolean forceInside) {
|
if (null == view) {
|
return false;
|
}
|
Context context = view.getContext();
|
RectF rect = getGlobalRect(view);
|
return isRectInScreen(context, rect, forceInside);
|
}
|
|
/**
|
* 判断当前view是否完全可见
|
* @return
|
*/
|
public static boolean isViewCovered(View view) {
|
Rect currentViewRect = new Rect();
|
boolean partVisible = view.getGlobalVisibleRect(currentViewRect);
|
boolean totalHeightVisible = (currentViewRect.bottom - currentViewRect.top) >= view.getMeasuredHeight();
|
boolean totalWidthVisible = (currentViewRect.right - currentViewRect.left) >= view.getMeasuredWidth();
|
boolean totalViewVisible = partVisible && totalHeightVisible && totalWidthVisible;
|
if (!totalViewVisible)//if any part of the view is clipped by any of its parents,return true
|
return true;
|
|
if (view.getParent() instanceof ViewGroup) {
|
ViewGroup currentParent = (ViewGroup) view.getParent();
|
if (currentParent.getVisibility() != View.VISIBLE)//if the parent of view is not visible,return true
|
return true;
|
|
if (view.getBottom() <= currentParent.getBottom()) {
|
return false;
|
}
|
}
|
return true;
|
}
|
|
/**
|
* 判断当前rect是否出现在可视窗口
|
*
|
* @param context 上下文
|
* @param rect 视图的矩阵区域
|
* @param forceInside 是否所有区域都在出现在屏幕内
|
* @return
|
*/
|
public static boolean isRectInScreen(Context context, RectF rect, boolean forceInside) {
|
if (null == context || null == rect) {
|
return false;
|
}
|
Rect screen = ScreenUtils.getAppDisplayRect(context, 0);
|
if (forceInside) {
|
//任何一个顶点 超出屏幕区域,则判定为超出屏幕区域
|
boolean invalid = (rect.left > screen.width() || rect.left < 0)
|
|| (rect.right > screen.width() || rect.right < 0)//
|
|| (rect.top > screen.height() || rect.top < 0)//
|
|| (rect.bottom > screen.height() || rect.bottom < 0);
|
return !invalid;
|
} else {
|
//任何一个顶点在屏幕区域内,则判定为出现在屏幕中
|
return (rect.left < screen.width() && rect.left > 0)
|
|| (rect.right < screen.width() && rect.right > 0)//
|
|| (rect.top < screen.height() && rect.top > 0)//
|
|| (rect.bottom < screen.height() && rect.bottom > 0);
|
}
|
}
|
|
/**
|
* 隐藏NavBar
|
*/
|
public static void hideNavBar(Context mContext, Dialog mDialog) {
|
if (!hasNavBar(mContext)||mDialog==null) {
|
return;
|
}
|
Window window = mDialog.getWindow();
|
if (window != null) {
|
mDialog.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
mDialog.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
|
@Override
|
public void onSystemUiVisibilityChange(int visibility) {
|
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
//布局位于状态栏下方
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
//全屏
|
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
//隐藏导航栏
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
uiOptions |= 0x00001000;
|
mDialog.getWindow().getDecorView().setSystemUiVisibility(uiOptions);
|
}
|
});
|
}
|
}
|
|
public static Rect getScreenRectNoStatusAndNav(@NonNull Context context) {
|
Rect deviceScreenRect = ScreenUtils.getDeviceScreenRect(context, 0);
|
Rect displayRect = new Rect();
|
displayRect.left = deviceScreenRect.left;
|
displayRect.top = deviceScreenRect.top + ScreenUtils.getSystemStatusBarHeight(context);
|
displayRect.right = deviceScreenRect.right;
|
if (ScreenUtil.hasNavigationBar(context)) {
|
displayRect.bottom = deviceScreenRect.bottom - getBottomNavBarHeight(context);
|
} else {
|
displayRect.bottom = deviceScreenRect.bottom;
|
}
|
return displayRect;
|
}
|
|
|
/**
|
* 兼容全面屏是否存在导航栏
|
* @param context non null
|
* @return true 有导航啦
|
*/
|
public static boolean hasNavigationBar(Context context) {
|
if (getNavigationBarHeight(context) == 0) {
|
return false;
|
} else if (RomUtils.isHuawei() && isHuaWeiHideNav(context)) {
|
return false;
|
} else if (RomUtils.isXiaomi() && xiaomiHasNavBar(context)) {
|
return false;
|
} else if (RomUtils.isVivo() && isVivoFullScreen(context)) {
|
return false;
|
} else {
|
return isHasNavigationBar(context);
|
}
|
}
|
|
private static boolean isHuaWeiHideNav(Context context) {
|
return Settings.Global.getInt(context.getContentResolver(), "navigationbar_is_min", 0) != 0;
|
}
|
|
private static boolean isVivoFullScreen(Context context) {
|
return Settings.Secure.getInt(context.getContentResolver(), "navigation_gesture_on", 0) != 0;
|
}
|
|
|
private static boolean isHasNavigationBar(Context context){
|
|
WindowManager windowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);
|
Display d = windowManager.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;
|
|
// 部分无良厂商的手势操作,显示高度 + 导航栏高度,竟然大于物理高度,对于这种情况,直接默认未启用导航栏
|
if (displayHeight + getNavigationBarHeight(context)> realHeight) return false;
|
|
return realWidth - displayWidth > 0 || realHeight - displayHeight > 0;
|
}
|
|
public static int getNavigationBarHeight(Context context) {
|
int result = 0;
|
int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
if (resourceId > 0) {
|
result = context.getResources().getDimensionPixelSize(resourceId);
|
}
|
return result;
|
}
|
}
|