如何真正获得 Android 中的导航栏高度
How to REALLY get the navigation bar height in Android
我有一台 HTC One A9,它可以隐藏导航栏。在我的应用程序中,我需要获取导航栏的高度并设置与之对应的内边距。这是我现在的问题:当我隐藏导航栏时,填充仍在设置中(甚至 Snapchat 也有这个问题)。我的问题是:是否有替代代码使其工作?
public static int getNavBarHeight(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;
}
感谢您的帮助!
这是我用来获取导航栏大小的代码。它的高度将在 Point.y
归功于 this answer
public static Point getNavigationBarSize(Context context) {
Point appUsableSize = getAppUsableScreenSize(context);
Point realScreenSize = getRealScreenSize(context);
// navigation bar on the right
if (appUsableSize.x < realScreenSize.x) {
return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
}
// navigation bar at the bottom
if (appUsableSize.y < realScreenSize.y) {
return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
}
// navigation bar is not present
return new Point();
}
public static Point getAppUsableScreenSize(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
public static Point getRealScreenSize(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
if (Build.VERSION.SDK_INT >= 17) {
display.getRealSize(size);
} else if (Build.VERSION.SDK_INT >= 14) {
try {
size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
} catch (IllegalAccessException e) {} catch (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
}
return size;
}
编辑:为了回答您的问题,我不得不使用此功能,因为我想将 ResideMenu 添加到我的应用程序,但由于导航栏的原因,我的应用程序底部出现了一个奇怪的空白边距。
所以我这样编辑了 ResideMenu 添加的这个功能:
@Override
protected boolean fitSystemWindows(Rect insets) {
// Applies the content insets to the view's padding, consuming that content (modifying the insets to be 0),
// and returning true. This behavior is off by default and can be enabled through setFitsSystemWindows(boolean)
// in API14+ devices.
int bottomPadding = insets.bottom;
Point p = getNavigationBarSize(getContext());
if (Build.VERSION.SDK_INT >= 21 && p.x != 0) {
Resources resources = getContext().getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
bottomPadding += resources.getDimensionPixelSize(resourceId);
}
}
this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top,
viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + bottomPadding);
insets.left = insets.top = insets.right = insets.bottom = 0;
return true;
}
希望对你有所帮助。
使用以下代码获取导航栏。但是,您需要考虑 Multi window 模式以及导航栏是在 window 的底部还是左侧或右侧。
getNavigationBarHeight(){
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
fun Context.isSoftNavigationBarAvailable(): Boolean {
val navBarInteractionModeId = resources.getIdentifier(
"config_navBarInteractionMode",
"integer",
"android"
)
if (navBarInteractionModeId > 0 && resources.getInteger(navBarInteractionModeId) > 0) {
// nav gesture is enabled in the settings
return false
}
val appUsableScreenSize = Point()
val realScreenSize = Point()
val defaultDisplay = (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
defaultDisplay.getSize(appUsableScreenSize)
defaultDisplay.getRealSize(realScreenSize)
return appUsableScreenSize.y < realScreenSize.y }
这里是最简单的答案。你只需要传递activity的rootView。如果未显示条形,则高度将为 0。
View rootView;
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
final int statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top; // in px
final int navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom; // in px
// do something with the heights
return WindowInsetsCompat.CONSUMED;
});
我有一台 HTC One A9,它可以隐藏导航栏。在我的应用程序中,我需要获取导航栏的高度并设置与之对应的内边距。这是我现在的问题:当我隐藏导航栏时,填充仍在设置中(甚至 Snapchat 也有这个问题)。我的问题是:是否有替代代码使其工作?
public static int getNavBarHeight(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;
}
感谢您的帮助!
这是我用来获取导航栏大小的代码。它的高度将在 Point.y
归功于 this answer
public static Point getNavigationBarSize(Context context) {
Point appUsableSize = getAppUsableScreenSize(context);
Point realScreenSize = getRealScreenSize(context);
// navigation bar on the right
if (appUsableSize.x < realScreenSize.x) {
return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
}
// navigation bar at the bottom
if (appUsableSize.y < realScreenSize.y) {
return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
}
// navigation bar is not present
return new Point();
}
public static Point getAppUsableScreenSize(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
public static Point getRealScreenSize(Context context) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
if (Build.VERSION.SDK_INT >= 17) {
display.getRealSize(size);
} else if (Build.VERSION.SDK_INT >= 14) {
try {
size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
} catch (IllegalAccessException e) {} catch (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
}
return size;
}
编辑:为了回答您的问题,我不得不使用此功能,因为我想将 ResideMenu 添加到我的应用程序,但由于导航栏的原因,我的应用程序底部出现了一个奇怪的空白边距。
所以我这样编辑了 ResideMenu 添加的这个功能:
@Override
protected boolean fitSystemWindows(Rect insets) {
// Applies the content insets to the view's padding, consuming that content (modifying the insets to be 0),
// and returning true. This behavior is off by default and can be enabled through setFitsSystemWindows(boolean)
// in API14+ devices.
int bottomPadding = insets.bottom;
Point p = getNavigationBarSize(getContext());
if (Build.VERSION.SDK_INT >= 21 && p.x != 0) {
Resources resources = getContext().getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
bottomPadding += resources.getDimensionPixelSize(resourceId);
}
}
this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top,
viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + bottomPadding);
insets.left = insets.top = insets.right = insets.bottom = 0;
return true;
}
希望对你有所帮助。
使用以下代码获取导航栏。但是,您需要考虑 Multi window 模式以及导航栏是在 window 的底部还是左侧或右侧。
getNavigationBarHeight(){
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
fun Context.isSoftNavigationBarAvailable(): Boolean {
val navBarInteractionModeId = resources.getIdentifier(
"config_navBarInteractionMode",
"integer",
"android"
)
if (navBarInteractionModeId > 0 && resources.getInteger(navBarInteractionModeId) > 0) {
// nav gesture is enabled in the settings
return false
}
val appUsableScreenSize = Point()
val realScreenSize = Point()
val defaultDisplay = (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
defaultDisplay.getSize(appUsableScreenSize)
defaultDisplay.getRealSize(realScreenSize)
return appUsableScreenSize.y < realScreenSize.y }
这里是最简单的答案。你只需要传递activity的rootView。如果未显示条形,则高度将为 0。
View rootView;
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
final int statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top; // in px
final int navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom; // in px
// do something with the heights
return WindowInsetsCompat.CONSUMED;
});