Android自定义Drawable在inflate中无法获取XML自定义属性值
问题解决:自定义GradientDrawable无法获取XML中的自定义属性
核心问题分析
导致属性读取失败的关键原因有两个:
- XML语法与类名错误:
test_drawable.xml里的class属性值写错了类名,且引号未闭合,系统无法正确实例化你的MyDrawable类,重写的inflate方法根本没被执行。 - 属性读取的上下文处理不足:即使类实例化正确,未结合主题上下文获取属性也可能导致读取失败。
分步修复方案
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
相关产品推荐
相关产品推荐

