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

Android自定义Drawable在inflate中无法获取XML自定义属性值

问题解决:自定义GradientDrawable无法获取XML中的自定义属性

核心问题分析

导致属性读取失败的关键原因有两个:

  1. XML语法与类名错误:test_drawable.xml里的class属性值写错了类名,且引号未闭合,系统无法正确实例化你的MyDrawable类,重写的inflate方法根本没被执行。
  2. 属性读取的上下文处理不足:即使类实例化正确,未结合主题上下文获取属性也可能导致读取失败。

分步修复方案

1. 修正test_drawable.xml的语法与类名

原XML存在类名错误和引号未闭合的问题,修正后代码如下:

<?xml version="1.0" encoding="utf-8"?>
<drawable xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    class="com.test.app.MyDrawable"
    app:radiusPercentage="50" />

2. 优化MyDrawable的inflate方法

结合主题上下文获取TypedArray,同时规范回收TypedArray避免内存泄漏:

class MyDrawable : GradientDrawable() {
    private var radiusPercentage: Int = 25

    override fun inflate(
        r: Resources,
        parser: XmlPullParser,
        attrs: AttributeSet,
        theme: Resources.Theme?
    ) {
        super.inflate(r, parser, attrs, theme)
        // 优先用主题上下文获取属性,适配不同主题场景
        val typedArray = theme?.obtainStyledAttributes(attrs, R.styleable.MyDrawable, 0, 0)
            ?: r.obtainAttributes(attrs, R.styleable.MyDrawable)
        
        // 读取属性值,默认值和初始值保持一致
        radiusPercentage = typedArray.getInteger(R.styleable.MyDrawable_radiusPercentage, 25)
        
        // 必须回收TypedArray
        typedArray.recycle()
    }
}

3. 验证实例化逻辑

你当前使用AppCompatResources.getDrawable的方式是正确的,若在布局中直接引用,需确保命名空间app:正确:

binding.container.background = AppCompatResources.getDrawable(context, R.drawable.test_drawable)

额外检查点

  • 确认自定义属性的declare-styleable名称与类名完全一致(你已正确设置为MyDrawable)。
  • 清理项目并重新构建,避免缓存导致的类加载异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:43:35