文章目录
ScreenSizeUtil
在 Android 开发中,获取屏幕尺寸是高频需求,但不同系统版本(尤其是 API 30 前后)的 API 差异、状态栏 / 导航栏的扣除逻辑、分屏 / 折叠屏适配等问题,很容易导致尺寸计算错误。本文分享一套兼容所有 Android 版本的屏幕尺寸工具类,支持获取设备物理尺寸、应用可用尺寸,还能单独获取状态栏 / 导航栏高度,解决日常开发中 99% 的屏幕尺寸适配问题
完整工具类
kotlin
object ScreenSizeUtil {
/**
* @describe: 获取当前设备的宽高,包含了状态栏、导航栏
* 1.忽略了分屏、画中画,始终返回当前设备最大尺寸
* 2.折叠屏时返回展开态时的设备最大尺寸
* @params:
* @return: Pair<Int,Int> 宽度与高度
*/
fun getScreenDevicesSize(context: Context): Pair<Int, Int> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { //30以上的适配
val bounds = context.windowManager.maximumWindowMetrics.bounds //获取当前设备的屏幕信息
bounds.height()
Pair(bounds.width(), bounds.height())
} else { //低版本适配
//方法1 获取实际的物理尺寸,包含状态栏跟导航栏
val display = context.displayManager.getDisplay(Display.DEFAULT_DISPLAY)
val physicalWidth = display.mode.physicalWidth
val physicalHeight = display.mode.physicalHeight
Pair(physicalWidth, physicalHeight)
//方法2 获取实际的物理尺寸,包含状态栏跟导航栏
/*val display = context.windowManager.defaultDisplay
val point = Point()
display.getRealSize(point)
Pair(point.x,point.y)*/
}
}
/**
* @describe: 获取应用可用高度,减去了状态栏、导航栏
* 1.返回画中画、分屏中当前窗口占用的区域,
* 2.折叠屏时返回折叠态的小屏高度
* @params:
* @return: Pair<Int,Int> 宽度与高度
*/
fun getAppUsableSize(context: Context): Pair<Int, Int> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val windowManager =
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val windowMetrics = windowManager.currentWindowMetrics //获取当前窗口的信息
val insets = windowMetrics.windowInsets
.getInsetsIgnoringVisibility(android.view.WindowInsets.Type.systemBars()) //排除系统插入区域(状态栏+导航栏)后的可见区域
// 应用高度 = 窗口高度 - 状态栏高度 - 导航栏高度
val height = windowMetrics.bounds.height() - insets.top - insets.bottom
val width = windowMetrics.bounds.width() - insets.left - insets.right
Pair(width, height)
} else {
// 方法1 获取当前窗口的宽高
val decorView = (context as android.app.Activity).window.decorView
val outRect = Rect()
decorView.getWindowVisibleDisplayFrame(outRect)
Pair(outRect.right - outRect.left, outRect.bottom - outRect.top)
//方法2 获取当前窗口的宽高
/* val meterics = DisplayMetrics()
context.windowManager.defaultDisplay.getMetrics(meterics)
Pair(meterics.widthPixels,meterics.heightPixels - getStatusBarHeight(context)) //老版本默认包含状态栏*/
//方法3.获取当前窗口的宽高
/*val display = context.windowManager.defaultDisplay
val point = Point()
display.getSize(point)
Pair(point.x,point.y - getStatusBarHeight(context)) //老版本默认包含状态栏*/
}
}
/**
* 获取状态栏高度
*
* @param context
* @return
*/
fun getStatusBarHeight(context: Context): Int {
val resourceId =
context.resources.getIdentifier("status_bar_height", "dimen", "android")
return context.resources.getDimensionPixelSize(resourceId)
}
/**
* 获取导航栏高度
*
* @param context
* @return
*/
fun getNavigationBarHeight(context: Context): Int {
val resourceId =
context.resources.getIdentifier("navigation_bar_height", "dimen", "android")
return context.resources.getDimensionPixelSize(resourceId)
}
/**
* @describe: 返回当前屏幕的密度
* @params: 上下文
* @return:
*/
fun getDisplayMetrics(context: Context): Float {
val displayMetrics = DisplayMetrics()
context.windowManager.defaultDisplay.getMetrics(displayMetrics)
return displayMetrics.density
}
}