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
    }
}
相关推荐
风流倜傥唐伯虎3 小时前
./gradlew assembleDebug和gradle build区别
android·android studio
那年我七岁4 小时前
android ndk c++ 绘制图片方式
android·c++·python
Java后端的Ai之路4 小时前
【Python教程10】-开箱即用
android·开发语言·python
2601_949809594 小时前
flutter_for_openharmony家庭相册app实战+隐私设置实现
android·javascript·flutter
我命由我123454 小时前
Android 开发 Room 数据库升级问题:A migration from 6 to 7 was required but not found.
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
2601_949543014 小时前
Flutter for OpenHarmony垃圾分类指南App实战:资讯详情实现
android·java·flutter
JMchen12315 小时前
现代Android图像处理管道:从CameraX到OpenGL的60fps实时滤镜架构
android·图像处理·架构·kotlin·android studio·opengl·camerax
快点好好学习吧16 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
是誰萆微了承諾16 小时前
php 对接deepseek
android·开发语言·php