You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Android Drawable中定义的宽高尺寸?

获取GradientDrawable中XML定义的Size尺寸

你可以通过以下几种方式获取shape Drawable中<size>标签定义的宽高:

方法一:利用intrinsicWidth/intrinsicHeight(推荐)

GradientDrawable的intrinsicWidth和intrinsicHeight方法会直接返回<size>标签定义的尺寸(单位为像素),你可以再转换为dp:

val drawable: GradientDrawable = getDrawable(R.drawable.small) as GradientDrawable
val widthPx = drawable.intrinsicWidth
val heightPx = drawable.intrinsicHeight

// 将像素转换为dp
val displayMetrics = resources.displayMetrics
val widthDp = (widthPx / displayMetrics.density).toInt()
val heightDp = (heightPx / displayMetrics.density).toInt()

注意:如果shape没有定义<size>,这两个方法会返回-1,需要做判空处理。

方法二:直接解析原始XML资源文件

如果需要直接获取XML中写的dp数值(不经过像素转换),可以直接解析Drawable的XML资源:

val resId = R.drawable.small
val parser = resources.getXml(resId)
var widthDp = 0
var heightDp = 0

try {
    var eventType = parser.eventType
    while (eventType != XmlPullParser.END_DOCUMENT) {
        if (eventType == XmlPullParser.START_TAG && parser.name == "size") {
            // 提取width和height的dp值
            widthDp = parser.getAttributeValue(null, "android:width")?.removeSuffix("dp")?.toInt() ?: 0
            heightDp = parser.getAttributeValue(null, "android:height")?.removeSuffix("dp")?.toInt() ?: 0
            break // 找到size标签后退出循环
        }
        eventType = parser.next()
    }
} catch (e: Exception) {
    e.printStackTrace()
}

方法三:反射获取内部字段(不推荐)

GradientDrawable内部会存储尺寸信息,但不同Android版本的字段名可能有变化,反射方式兼容性较差:

try {
    val drawable: GradientDrawable = getDrawable(R.drawable.small) as GradientDrawable
    // 反射获取mWidth和mHeight字段(像素值)
    val widthField = GradientDrawable::class.java.getDeclaredField("mWidth")
    widthField.isAccessible = true
    val widthPx = widthField.getInt(drawable)

    val heightField = GradientDrawable::class.java.getDeclaredField("mHeight")
    heightField.isAccessible = true
    val heightPx = heightField.getInt(drawable)

    // 转换为dp
    val displayMetrics = resources.displayMetrics
    val widthDp = (widthPx / displayMetrics.density).toInt()
    val heightDp = (heightPx / displayMetrics.density).toInt()
} catch (e: NoSuchFieldException) {
    // 适配不同版本的字段名,比如部分版本用mSize数组
    try {
        val sizeField = GradientDrawable::class.java.getDeclaredField("mSize")
        sizeField.isAccessible = true
        val size = sizeField.get(drawable) as IntArray
        val widthPx = size[0]
        val heightPx = size[1]
        
        val displayMetrics = resources.displayMetrics
        val widthDp = (widthPx / displayMetrics.density).toInt()
        val heightDp = (heightPx / displayMetrics.density).toInt()
    } catch (ex: Exception) {
        ex.printStackTrace()
    }
} catch (e: IllegalAccessException) {
    e.printStackTrace()
}

内容的提问来源于stack exchange,提问作者user1332148

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:35:29