没有状态栏、actionBar 和选项卡的屏幕高度

Height of screen without status bar, actionBar and tabs

我有一个 ListView,我希望每一行都填满可用屏幕的三分之一。我有一个可见的状态栏,然后是一个带有 slidingTabs 的 actionBar。我正在像这样进行当前计算:

height = context.getResources().getDisplayMetrics().heightPixels;
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
    {
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,context.getResources().getDisplayMetrics());
        Log.d("actionBarHeigth", actionBarHeight.toString());
    }

并像这样设置视图高度:

holder.imageView.getLayoutParams().height = (height - actionBarHeight*2) / 3;

但是列表的行有点太大了,我猜是状态栏导致的。如何将它的高度添加到我的计算中?

您可以使用此代码:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
}

如此处所述:

请尝试使用此解决方案并告诉我们它是否有效。 ;)

根据@rasmeta 的回答,我编写了这段代码,它成功了。我的行现在恰好是可用屏幕的三分之一。下面是获取状态栏高度的方法:

int resource = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resource > 0) {
        statusBarHeight = context.getResources().getDimensionPixelSize(resource);
    }

每行的高度计算如下:

holder.imageView.getLayoutParams().height = (screenHeight - statusBarHeight - actionBarHeight*2) / 3;
// actionBarHeight * 2 because the tabs have the same height as the actionBar.

最简单的方法是这样的:

int height = findViewById(R.id.rootView).getHeight();

rootView 是主根布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
      ...
</LinearLayout>

这里有一些可以帮助你的扩展程序

fun Activity.heightScreen(): Int {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        windowManager.currentWindowMetrics.bounds.height()
    } else {
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        return displayMetrics.heightPixels
    }
}

/***
 * Gets the real ]Height of the display without subtracting any window decor or
 * applying any compatibility scale factors.
 * <p>
 * The size is adjusted based on the current rotation of the display.
 * @param view - your view
 */
fun Fragment.realHeightScreen(view: View = requireView()): Int {
    val point = Point()
    view.display.getRealSize(point)
    return point.y
}

/***
 *Gets the real Width of the display without subtracting any window decor or
 * applying any compatibility scale factors.
 * <p>
 * The size is adjusted based on the current rotation of the display.
 * @param view - your view
 */
fun Fragment.realWidthScreen(view: View = requireView()): Int {
    val point = Point()
    view.display.getRealSize(point)
    return point.x
}


fun getSoftNavigationBarSize(resources: Resources = Resources.getSystem()): Int {
    var result = 0
    val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android")
    if (resourceId > 0) {
        result = resources.getDimensionPixelSize(resourceId)
    }
    return result
}