Android中获取当前设备的宽高与屏幕密度等数据的工具类

文章目录


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
    }
}
相关推荐
aaajj1 分钟前
【Android】appops学习
android·学习
煤球王子17 分钟前
学习记录:Android14中的Wifi_Direct(P2P)
android
找藉口是失败者的习惯22 分钟前
【Android】Android 车机 + AI Agent 有没有搞头?
android·人工智能
用户004452159301 小时前
从 Gradle 到 Transform:Android 编译开发 Part 1 - Gradle 构建初探
android
用户004452159301 小时前
Android studio连接GitLab及使用(Windows版本)
android
zhouping@1 小时前
polarctf2025秋
android·web安全·php
0xSec笔记本挖呀瓦呀挖1 小时前
OpenClawWeComzh 实战:安卓 APK 分析与手机取证全自动化基础玩法
android·web安全·网络安全·智能手机·自动化·取证·电子数据取证
jolimark1 小时前
【mysql部署】在ubuntu22.04上安装和配置mysql教程
android·mysql·adb
YSoup1 小时前
MAT最新下载地址及Android内存泄露排查简单使用
android
71-32 小时前
Android studio的安装下载(Android Studio Panda 1 | 2025.3.1 Patch 1 )
android·笔记·学习·android studio