Kev*_*vik 113 graphics user-interface android android-activity
Android屏幕底部的黑色导航栏无法轻松移除.它从3.0开始就是Android的一部分,作为硬件按钮的替代品.这是一张图片:

如何获得此UI元素的宽度和高度的大小(以像素为单位)?
San*_*ket 168
试试以下代码:
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
Run Code Online (Sandbox Code Playgroud)
Egi*_*gis 99
我通过将应用程序可用的屏幕大小与实际屏幕大小进行比较来获得导航栏大小 我认为当应用程序可用的屏幕尺寸小于实际屏幕尺寸时,存在导航栏.然后我计算导航栏的大小.此方法适用于API 14及更高版本.
public static Point getNavigationBarSize(Context context) {
Point appUsableSize = getAppUsableScreenSize(context);
Point realScreenSize = getRealScreenSize(context);
// navigation bar on the side
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;
}
Run Code Online (Sandbox Code Playgroud)
Mdl*_*dlc 35
NavigationBar高度因某些设备而异,但也适用于某些设备.首先,您必须检查设备是否有导航栏,然后是设备是平板电脑还是非平板电脑(手机),最后您必须查看设备的方向才能获得正确的高度.
public int getNavBarHeight(Context c) {
int result = 0;
boolean hasMenuKey = ViewConfiguration.get(c).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
if(!hasMenuKey && !hasBackKey) {
//The device has a navigation bar
Resources resources = c.getResources();
int orientation = resources.getConfiguration().orientation;
int resourceId;
if (isTablet(c)){
resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
} else {
resourceId = resources.getIdentifier(orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_width", "dimen", "android");
}
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
}
return result;
}
private boolean isTablet(Context c) {
return (c.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*okh 26
实际上平板电脑上的导航栏(至少是Nexus 7)在纵向和横向上有不同的大小,所以这个功能应该如下所示:
private int getNavigationBarHeight(Context context, int orientation) {
Resources resources = context.getResources();
int id = resources.getIdentifier(
orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape",
"dimen", "android");
if (id > 0) {
return resources.getDimensionPixelSize(id);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ohn 15
我认为更正确的答案在这里,因为它也允许你采取甚至切割高度.
获取您的根视图,并向其添加setOnApplyWindowInsetsListener(或者您可以从中覆盖onApplyWindowInsets),并从中获取insets.getSystemWindowInsets.
在我的相机活动中,我添加等于systemWindowInsetBottom的填充到我的底部布局.最后,它解决了切断问题.
与appcompat它是这样的
ViewCompat.setOnApplyWindowInsetsListener(mCameraSourcePreview, (v, insets) -> {
takePictureLayout.setPadding(0,0,0,insets.getSystemWindowInsetBottom());
return insets.consumeSystemWindowInsets();
});
Run Code Online (Sandbox Code Playgroud)
没有appcompat,这个:
mCameraSourcePreview.setOnApplyWindowInsetsListener((v, insets) -> { ... })
Run Code Online (Sandbox Code Playgroud)
小智 10
我希望这可以帮助你
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
public int getNavigationBarHeight()
{
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0 && !hasMenuKey)
{
return getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
灵感来自Egis的回答:
context.navigationBarHeight
Run Code Online (Sandbox Code Playgroud)
扩展吸气剂在哪里
val Context.navigationBarHeight: Int
get() {
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
return if (Build.VERSION.SDK_INT >= 30) {
windowManager
.currentWindowMetrics
.windowInsets
.getInsets(WindowInsets.Type.navigationBars())
.bottom
} else {
val currentDisplay = try {
display
} catch (e: NoSuchMethodError) {
windowManager.defaultDisplay
}
val appUsableSize = Point()
val realScreenSize = Point()
currentDisplay?.apply {
getSize(appUsableSize)
getRealSize(realScreenSize)
}
// navigation bar on the side
if (appUsableSize.x < realScreenSize.x) {
return realScreenSize.x - appUsableSize.x
}
// navigation bar at the bottom
return if (appUsableSize.y < realScreenSize.y) {
realScreenSize.y - appUsableSize.y
} else 0
}
}
Run Code Online (Sandbox Code Playgroud)
测试于:
小智 5
这是我将paddingRight和paddingBottom添加到View以避开导航栏的代码.我在这里结合了一些答案,并与isInMultiWindowMode一起制作了横向定向的特殊条款.关键是要阅读navigation_bar_height,还要检查config_showNavigationBar以确保我们应该实际使用高度.
以前的解决方案都不适合我.从Android 7.0开始,您必须考虑多窗口模式.这打破了将display.realSize与display.size进行比较的实现,因为realSize为您提供了整个屏幕的尺寸(两个分割窗口),而尺寸只为您提供了应用窗口的尺寸.将填充设置为此差异将使整个视图成为填充.
/** Adds padding to a view to dodge the navigation bar.
Unfortunately something like this needs to be done since there
are no attr or dimens value available to get the navigation bar
height (as of December 2016). */
public static void addNavigationBarPadding(Activity context, View v) {
Resources resources = context.getResources();
if (hasNavigationBar(resources)) {
int orientation = resources.getConfiguration().orientation;
int size = getNavigationBarSize(resources);
switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
context.isInMultiWindowMode()) { break; }
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(),
v.getPaddingRight() + size, v.getPaddingBottom());
break;
case Configuration.ORIENTATION_PORTRAIT:
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(),
v.getPaddingRight(), v.getPaddingBottom() + size);
break;
}
}
}
private static int getNavigationBarSize(Resources resources) {
int resourceId = resources.getIdentifier("navigation_bar_height",
"dimen", "android");
return resourceId > 0 ? resources.getDimensionPixelSize(resourceId) : 0;
}
private static boolean hasNavigationBar(Resources resources) {
int hasNavBarId = resources.getIdentifier("config_showNavigationBar",
"bool", "android");
return hasNavBarId > 0 && resources.getBoolean(hasNavBarId);
}
Run Code Online (Sandbox Code Playgroud)