以前公共库里的代码,发现是使用如下代码获取状态栏高度的:
/**
* 获取状态栏高度
* */
int statusBarH = 0;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
statusBarH = getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusBarH;
其实从 Android 9 开始,就已经对通过反射调用非公开 API 的方式进行警告了。
Android 11以前的系统,只是给出警告, Android 11直接抛出了调用异常。
于是搜索一下,发现网上已经更改成如下方法了:
方案一:
int statusBarH = 0;
//获取status_bar_height资源的ID
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根据资源ID获取响应的尺寸值
statusBarH = getResources().getDimensionPixelSize(resourceId);
}
return statusBarH;
仔细观察两个方法,会发现,其实两者都是获取了系统里的状态栏使用的某个资源的高度信息,然后作为状态栏的高度信息。
另外,网上流传的另一段代码
方案二:
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
方案三:
WindowMetrics是Android
11新增的类,用于获取窗口边界,同样可以用来获取导航栏高度。
public static int getStatusBarHeight(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
WindowInsets windowInsets = windowMetrics.getWindowInsets();
Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
return insets.top;
}
....
}