This commit is contained in:
coco
2026-07-03 16:23:31 +08:00
commit 7a4fb0e6ae
1979 changed files with 101570 additions and 0 deletions
@@ -0,0 +1 @@
/build
@@ -0,0 +1,68 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize'
apply plugin: 'com.google.dagger.hilt.android'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
multiDexEnabled true
consumerProguardFiles "consumer-rules.pro"
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation":"$projectDir/schemas".toString(),
"room.incremental":"true",
"room.expandProjection":"true",
AROUTER_MODULE_NAME: project.getName()
]
}
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
buildFeatures {
viewBinding true
}
}
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
generateStubs = true
useBuildCache = true
javacOptions {
option("-Xmaxerrs", 500)
}
}
dependencies {
compileOnly(rootProject.ext.jetpack["hilt"])
kapt rootProject.ext.compiler["hiltAndroidCompiler"]
}
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,24 @@
package com.bbgo.library_statusbar
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.bbgo.library_statusbar.test", appContext.packageName)
}
}
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bbgo.library_statusbar">
</manifest>
@@ -0,0 +1,32 @@
package com.bbgo.library_statusbar;
import android.app.Activity;
import android.graphics.Rect;
import java.util.List;
public interface INotchScreen {
boolean hasNotch(Activity activity);
void setDisplayInNotch(Activity activity);
void getNotchRect(Activity activity, NotchSizeCallback callback);
interface NotchSizeCallback {
void onResult(List<Rect> notchRects);
}
interface HasNotchCallback {
void onResult(boolean hasNotch);
}
interface NotchScreenCallback {
void onResult(NotchScreenInfo notchScreenInfo);
}
class NotchScreenInfo {
public boolean hasNotch;
public List<Rect> notchRects;
}
}
@@ -0,0 +1,68 @@
package com.bbgo.library_statusbar;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import com.bbgo.library_statusbar.impl.AndroidPNotchScreen;
import com.bbgo.library_statusbar.impl.HuaweiNotchScreen;
import com.bbgo.library_statusbar.impl.MiNotchScreen;
import com.bbgo.library_statusbar.impl.OppoNotchScreen;
import com.bbgo.library_statusbar.utils.RomUtils;
import java.util.List;
public class NotchScreenManager {
private static final NotchScreenManager instance = new NotchScreenManager();
private final INotchScreen notchScreen;
private NotchScreenManager() {
notchScreen = getNotchScreen();
}
public static NotchScreenManager getInstance() {
return instance;
}
public void setDisplayInNotch(Activity activity) {
if (notchScreen != null)
notchScreen.setDisplayInNotch(activity);
}
public void getNotchInfo(final Activity activity, final INotchScreen.NotchScreenCallback notchScreenCallback) {
final INotchScreen.NotchScreenInfo notchScreenInfo = new INotchScreen.NotchScreenInfo();
if (notchScreen != null && notchScreen.hasNotch(activity)) {
notchScreen.getNotchRect(activity, new INotchScreen.NotchSizeCallback() {
@Override
public void onResult(List<Rect> notchRects) {
if (notchRects != null && notchRects.size() > 0) {
notchScreenInfo.hasNotch = true;
notchScreenInfo.notchRects = notchRects;
}
notchScreenCallback.onResult(notchScreenInfo);
}
});
} else {
notchScreenCallback.onResult(notchScreenInfo);
}
}
private INotchScreen getNotchScreen() {
INotchScreen notchScreen = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
notchScreen = new AndroidPNotchScreen();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (RomUtils.isHuawei()) {
notchScreen = new HuaweiNotchScreen();
} else if (RomUtils.isOppo()) {
notchScreen = new OppoNotchScreen();
} else if (RomUtils.isVivo()) {
notchScreen = new HuaweiNotchScreen();
} else if (RomUtils.isXiaomi()) {
notchScreen = new MiNotchScreen();
}
}
return notchScreen;
}
}
@@ -0,0 +1,60 @@
package com.bbgo.library_statusbar.impl;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import com.bbgo.library_statusbar.INotchScreen;
import java.util.List;
@TargetApi(Build.VERSION_CODES.P)
public class AndroidPNotchScreen implements INotchScreen {
/**
* Android P 没有单独的判断方法,根据getNotchRect方法的返回结果处理即可
*/
@Override
public boolean hasNotch(Activity activity) {
return true;
}
@Override
public void setDisplayInNotch(Activity activity) {
Window window = activity.getWindow();
// 延伸显示区域到耳朵区
WindowManager.LayoutParams lp = window.getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
window.setAttributes(lp);
// 允许内容绘制到耳朵区
final View decorView = window.getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
@Override
public void getNotchRect(Activity activity, final NotchSizeCallback callback) {
final View contentView = activity.getWindow().getDecorView();
contentView.post(new Runnable() {
@Override
public void run() {
WindowInsets windowInsets = contentView.getRootWindowInsets();
if (windowInsets != null) {
DisplayCutout cutout = windowInsets.getDisplayCutout();
if (cutout != null) {
List<Rect> rects = cutout.getBoundingRects();
callback.onResult(rects);
return;
}
}
callback.onResult(null);
}
});
}
}
@@ -0,0 +1,84 @@
package com.bbgo.library_statusbar.impl;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.Window;
import android.view.WindowManager;
import com.bbgo.library_statusbar.INotchScreen;
import com.bbgo.library_statusbar.utils.ScreenUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
@TargetApi(Build.VERSION_CODES.O)
public class HuaweiNotchScreen implements INotchScreen {
/**
* 刘海屏全屏显示FLAG
*/
public static final int FLAG_NOTCH_SUPPORT = 0x00010000;
/**
* 设置华为刘海屏手机不使用刘海区
*/
public static void setNotDisplayInNotch(Activity activity) {
try {
Window window = activity.getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
Constructor con = layoutParamsExCls.getConstructor(WindowManager.LayoutParams.class);
Object layoutParamsExObj = con.newInstance(layoutParams);
Method method = layoutParamsExCls.getMethod("clearHwFlags", int.class);
method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
window.getWindowManager().updateViewLayout(window.getDecorView(), window.getDecorView().getLayoutParams());
} catch (Throwable ignore) {
}
}
@Override
public boolean hasNotch(Activity activity) {
boolean ret = false;
try {
ClassLoader cl = activity.getClassLoader();
Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
ret = (boolean) get.invoke(HwNotchSizeUtil);
} catch (Throwable ignore) {
}
return ret;
}
@Override
public void setDisplayInNotch(Activity activity) {
try {
Window window = activity.getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
Constructor con = layoutParamsExCls.getConstructor(WindowManager.LayoutParams.class);
Object layoutParamsExObj = con.newInstance(layoutParams);
Method method = layoutParamsExCls.getMethod("addHwFlags", int.class);
method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
window.getWindowManager().updateViewLayout(window.getDecorView(), window.getDecorView().getLayoutParams());
} catch (Throwable ignore) {
}
}
@Override
public void getNotchRect(Activity activity, NotchSizeCallback callback) {
try {
ClassLoader cl = activity.getClassLoader();
Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
Method get = HwNotchSizeUtil.getMethod("getNotchSize");
int[] ret = (int[]) get.invoke(HwNotchSizeUtil);
ArrayList<Rect> rects = new ArrayList<>();
rects.add(ScreenUtil.calculateNotchRect(activity, ret[0], ret[1]));
callback.onResult(rects);
} catch (Throwable ignore) {
callback.onResult(null);
}
}
}
@@ -0,0 +1,67 @@
package com.bbgo.library_statusbar.impl;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.view.Window;
import com.bbgo.library_statusbar.INotchScreen;
import com.bbgo.library_statusbar.utils.ScreenUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
@TargetApi(Build.VERSION_CODES.O)
public class MiNotchScreen implements INotchScreen {
private static boolean isNotch() {
try {
Method getInt = Class.forName("android.os.SystemProperties").getMethod("getInt", String.class, int.class);
int notch = (int) getInt.invoke(null, "ro.miui.notch", 0);
return notch == 1;
} catch (Throwable ignore) {
}
return false;
}
public static int getNotchHeight(Context context) {
int resourceId = context.getResources().getIdentifier("notch_height", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
public static int getNotchWidth(Context context) {
int resourceId = context.getResources().getIdentifier("notch_width", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
@Override
public boolean hasNotch(Activity activity) {
return isNotch();
}
@Override
public void setDisplayInNotch(Activity activity) {
int flag = 0x00000100 | 0x00000200 | 0x00000400;
try {
Method method = Window.class.getMethod("addExtraFlags",
int.class);
method.invoke(activity.getWindow(), flag);
} catch (Exception ignore) {
}
}
@Override
public void getNotchRect(Activity activity, NotchSizeCallback callback) {
Rect rect = ScreenUtil.calculateNotchRect(activity, getNotchWidth(activity), getNotchHeight(activity));
ArrayList<Rect> rects = new ArrayList<>();
rects.add(rect);
callback.onResult(rects);
}
}
@@ -0,0 +1,94 @@
package com.bbgo.library_statusbar.impl;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import com.bbgo.library_statusbar.INotchScreen;
import com.bbgo.library_statusbar.utils.ScreenUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
@TargetApi(Build.VERSION_CODES.O)
public class OppoNotchScreen implements INotchScreen {
/**
* 获取刘海的坐标
* <p>
* 属性形如:[ro.oppo.screen.heteromorphism]: [378,0:702,80]
* <p>
* 获取到的值为378,0:702,80
* <p>
* <p>
* (378,0)是刘海区域左上角的坐标
* <p>
* (702,80)是刘海区域右下角的坐标
*/
private static String getScreenValue() {
String value = "";
Class<?> cls;
try {
cls = Class.forName("android.os.SystemProperties");
Method get = cls.getMethod("get", String.class);
Object object = cls.newInstance();
value = (String) get.invoke(object, "ro.oppo.screen.heteromorphism");
} catch (Throwable ignore) {
}
return value;
}
@Override
public boolean hasNotch(Activity activity) {
boolean ret = false;
try {
ret = activity.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
} catch (Throwable ignore) {
}
return ret;
}
@Deprecated
@Override
public void setDisplayInNotch(Activity activity) {
}
@Override
public void getNotchRect(Activity activity, NotchSizeCallback callback) {
try {
String screenValue = getScreenValue();
if (!TextUtils.isEmpty(screenValue)) {
String[] split = screenValue.split(":");
String leftTopPoint = split[0];
String[] leftAndTop = leftTopPoint.split(",");
String rightBottomPoint = split[1];
String[] rightAndBottom = rightBottomPoint.split(",");
int left;
int top;
int right;
int bottom;
if (ScreenUtil.isPortrait(activity)) {
left = Integer.valueOf(leftAndTop[0]);
top = Integer.valueOf(leftAndTop[1]);
right = Integer.valueOf(rightAndBottom[0]);
bottom = Integer.valueOf(rightAndBottom[1]);
} else {
left = Integer.valueOf(leftAndTop[1]);
top = Integer.valueOf(leftAndTop[0]);
right = Integer.valueOf(rightAndBottom[1]);
bottom = Integer.valueOf(rightAndBottom[0]);
}
Rect rect = new Rect(left, top, right, bottom);
ArrayList<Rect> rects = new ArrayList<>();
rects.add(rect);
callback.onResult(rects);
}
} catch (Throwable ignore) {
callback.onResult(null);
}
}
}
@@ -0,0 +1,74 @@
package com.bbgo.library_statusbar.impl;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.Log;
import com.bbgo.library_statusbar.INotchScreen;
import com.bbgo.library_statusbar.utils.ScreenUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* 测试之后发现vivo并不需要适配,因为vivo没有将显示区域绘制到耳朵区的API
*/
@TargetApi(Build.VERSION_CODES.O)
public class VivoNotchScreen implements INotchScreen {
public static boolean isNotch() {
boolean value = false;
int mask = 0x00000020;
try {
Class<?> cls = Class.forName("android.util.FtFeature");
Method hideMethod = cls.getMethod("isFtFeatureSupport", int.class);
Object object = cls.newInstance();
value = (boolean) hideMethod.invoke(object, mask);
} catch (Exception e) {
Log.e("tag", "get error() ", e);
}
return value;
}
/**
* vivo的适配文档中就告诉是27dp,未告知如何动态获取
*/
public static int getNotchHeight(Context context) {
float density = getDensity(context);
return (int) (27 * density);
}
/**
* vivo的适配文档中就告诉是100dp,未告知如何动态获取
*/
public static int getNotchWidth(Context context) {
float density = getDensity(context);
return (int) (100 * density);
}
private static float getDensity(Context context) {
return context.getResources().getDisplayMetrics().density;
}
@Override
public boolean hasNotch(Activity activity) {
return isNotch();
}
@Deprecated
@Override
public void setDisplayInNotch(Activity activity) {
}
@Override
public void getNotchRect(Activity activity, NotchSizeCallback callback) {
ArrayList<Rect> rects = new ArrayList<>();
Rect rect = ScreenUtil.calculateNotchRect(activity, getNotchWidth(activity), getNotchHeight(activity));
rects.add(rect);
callback.onResult(rects);
}
}
@@ -0,0 +1,234 @@
package com.bbgo.library_statusbar.utils;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.Properties;
public final class RomUtils {
private static final String HUAWEI = "huawei";
private static final String VIVO = "vivo";
private static final String XIAOMI = "xiaomi";
private static final String OPPO = "oppo";
private static final String VERSION_PROPERTY_HUAWEI = "ro.build.version.emui";
private static final String VERSION_PROPERTY_VIVO = "ro.vivo.os.build.display.id";
private static final String VERSION_PROPERTY_XIAOMI = "ro.build.version.incremental";
private static final String VERSION_PROPERTY_OPPO = "ro.build.version.opporom";
private static final String UNKNOWN = "unknown";
private static RomInfo bean = null;
private RomUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Return whether the rom is made by huawei.
*
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isHuawei() {
return HUAWEI.equals(getRomInfo().name);
}
/**
* Return whether the rom is made by vivo.
*
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isVivo() {
return VIVO.equals(getRomInfo().name);
}
/**
* Return whether the rom is made by xiaomi.
*
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isXiaomi() {
return XIAOMI.equals(getRomInfo().name);
}
/**
* Return whether the rom is made by oppo.
*
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isOppo() {
return OPPO.equals(getRomInfo().name);
}
/**
* Return the rom's information.
*
* @return the rom's information
*/
public static RomInfo getRomInfo() {
if (bean != null) return bean;
bean = new RomInfo();
final String brand = getBrand();
final String manufacturer = getManufacturer();
if (isRightRom(brand, manufacturer, HUAWEI)) {
bean.name = HUAWEI;
String version = getRomVersion(VERSION_PROPERTY_HUAWEI);
String[] temp = version.split("_");
if (temp.length > 1) {
bean.version = temp[1];
} else {
bean.version = version;
}
return bean;
}
if (isRightRom(brand, manufacturer, VIVO)) {
bean.name = VIVO;
bean.version = getRomVersion(VERSION_PROPERTY_VIVO);
return bean;
}
if (isRightRom(brand, manufacturer, XIAOMI)) {
bean.name = XIAOMI;
bean.version = getRomVersion(VERSION_PROPERTY_XIAOMI);
return bean;
}
if (isRightRom(brand, manufacturer, OPPO)) {
bean.name = OPPO;
bean.version = getRomVersion(VERSION_PROPERTY_OPPO);
return bean;
} else {
bean.name = manufacturer;
}
bean.version = getRomVersion("");
return bean;
}
private static boolean isRightRom(final String brand, final String manufacturer, final String... names) {
for (String name : names) {
if (brand.contains(name) || manufacturer.contains(name)) {
return true;
}
}
return false;
}
private static String getManufacturer() {
try {
String manufacturer = Build.MANUFACTURER;
if (!TextUtils.isEmpty(manufacturer)) {
return manufacturer.toLowerCase();
}
} catch (Throwable ignore) { /**/ }
return UNKNOWN;
}
private static String getBrand() {
try {
String brand = Build.BRAND;
if (!TextUtils.isEmpty(brand)) {
return brand.toLowerCase();
}
} catch (Throwable ignore) { /**/ }
return UNKNOWN;
}
private static String getRomVersion(final String propertyName) {
String ret = "";
if (!TextUtils.isEmpty(propertyName)) {
ret = getSystemProperty(propertyName);
}
if (TextUtils.isEmpty(ret) || ret.equals(UNKNOWN)) {
try {
String display = Build.DISPLAY;
if (!TextUtils.isEmpty(display)) {
ret = display.toLowerCase();
}
} catch (Throwable ignore) { /**/ }
}
if (TextUtils.isEmpty(ret)) {
return UNKNOWN;
}
return ret;
}
private static String getSystemProperty(final String name) {
String prop = getSystemPropertyByShell(name);
if (!TextUtils.isEmpty(prop)) return prop;
prop = getSystemPropertyByStream(name);
if (!TextUtils.isEmpty(prop)) return prop;
if (Build.VERSION.SDK_INT < 28) {
return getSystemPropertyByReflect(name);
}
return prop;
}
private static String getSystemPropertyByShell(final String propName) {
String line;
BufferedReader input = null;
try {
Process p = Runtime.getRuntime().exec("getprop " + propName);
input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
String ret = input.readLine();
if (ret != null) {
return ret;
}
} catch (IOException ignore) {
} finally {
if (input != null) {
try {
input.close();
} catch (IOException ignore) { /**/ }
}
}
return "";
}
private static String getSystemPropertyByStream(final String key) {
try {
Properties prop = new Properties();
FileInputStream is = new FileInputStream(
new File(Environment.getRootDirectory(), "build.prop")
);
prop.load(is);
return prop.getProperty(key, "");
} catch (Exception ignore) { /**/ }
return "";
}
private static String getSystemPropertyByReflect(String key) {
try {
@SuppressLint("PrivateApi")
Class<?> clz = Class.forName("android.os.SystemProperties");
Method getMethod = clz.getMethod("get", String.class, String.class);
return (String) getMethod.invoke(clz, key, "");
} catch (Exception e) { /**/ }
return "";
}
public static class RomInfo {
private String name;
private String version;
public String getName() {
return name;
}
public String getVersion() {
return version;
}
@Override
public String toString() {
return "RomInfo{name=" + name +
", version=" + version + "}";
}
}
}
@@ -0,0 +1,120 @@
package com.bbgo.library_statusbar.utils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
public class ScreenUtil {
public static boolean isPortrait(Context context) {
return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}
/**
* 获取contentView的高度,建议在onWindowFocusChanged之后调用,否则高度为0
*/
public static int getContentViewHeight(Activity activity) {
return getContentView(activity).getHeight();
}
/**
* 获取contentView的在屏幕上的展示区域,建议在onWindowFocusChanged之后调用
*/
public static Rect getContentViewDisplayFrame(Activity activity) {
View contentView = getContentView(activity);
Rect displayFrame = new Rect();
contentView.getWindowVisibleDisplayFrame(displayFrame);
return displayFrame;
}
public static View getContentView(Activity activity) {
return activity.getWindow().getDecorView().findViewById(android.R.id.content);
}
/**
* 获取navigationBar的高度
*/
public static int getNavigationBarHeight(Context context) {
return getDimensionPixel(context, "navigation_bar_height");
}
/**
* 获取statusBar的高度
*/
public static int getStatusBarHeight(Context context) {
return getDimensionPixel(context, "status_bar_height");
}
private static int getDimensionPixel(Context context, String navigation_bar_height) {
int result = 0;
Resources resources = context.getResources();
int resourceId = resources.getIdentifier(navigation_bar_height, "dimen", "android");
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 获取屏幕宽高
*/
public static int[] getScreenSize(Context context) {
int[] size = new int[2];
WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
if (Build.VERSION.SDK_INT >= 17)
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Throwable ignored) {
}
size[0] = widthPixels;
size[1] = heightPixels;
return size;
}
/**
* 通过宽高计算notch的Rect
*
* @param notchWidth 刘海的宽
* @param notchHeight 刘海的高
*/
public static Rect calculateNotchRect(Context context, int notchWidth, int notchHeight) {
int[] screenSize = getScreenSize(context);
int screenWidth = screenSize[0];
int screenHeight = screenSize[1];
int left;
int top;
int right;
int bottom;
if (isPortrait(context)) {
left = (screenWidth - notchWidth) / 2;
top = 0;
right = left + notchWidth;
bottom = notchHeight;
} else {
left = 0;
top = (screenHeight - notchWidth) / 2;
right = notchHeight;
bottom = top + notchWidth;
}
return new Rect(left, top, right, bottom);
}
}
@@ -0,0 +1,17 @@
package com.bbgo.library_statusbar
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}