自定义MaterialButton无法获取styles.xml中自定义属性问题
问题分析与解决方案
你遇到的这个TypedArray无法读取自定义属性的问题,主要有几个常见的原因,咱们一步步排查解决:
1. 避免declare-styleable命名冲突
你在attrs.xml里定义的declare-styleable名字是Button,但系统本身已经存在android.R.styleable.Button,这会导致命名冲突,使得TypedArray无法正确识别你的自定义属性。
解决方法:
把declare-styleable的名字改成更独特的,比如和你的自定义按钮类名对应,比如ProgressMaterialButton:
<declare-styleable name="ProgressMaterialButton"> <attr name="progressColor" format="color" /> <attr name="progressWidth" format="dimension" /> </declare-styleable>
然后在代码中同步修改引用:
private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int) { val ta = context.obtainStyledAttributes(attrs, R.styleable.ProgressMaterialButton, defStyleAttr, 0) try { val hasValue1 = ta.hasValue(R.styleable.ProgressMaterialButton_progressColor) val hasValue2 = ta.hasValue(R.styleable.ProgressMaterialButton_progressWidth) progressColor = ta.getColor(R.styleable.ProgressMaterialButton_progressColor, Color.WHITE) progressWidth = ta.getDimension(R.styleable.ProgressMaterialButton_progressWidth, 5f) } finally { ta.recycle() } }
2. 确保defStyleAttr参数正确传递
因为你的按钮继承自MaterialButton,它的默认样式属性是R.attr.materialButtonStyle。当你在主题中设置了materialButtonStyle为你的自定义样式,需要确保在获取TypedArray时,能正确关联到这个默认样式。
如果你的自定义按钮构造方法是这样的,就能保证布局未指定style时,TypedArray从主题的默认样式读取属性:
class ProgressMaterialButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.materialButtonStyle // 指定MaterialButton的默认样式属性 ) : MaterialButton(context, attrs, defStyleAttr) { init { init(context, attrs, defStyleAttr) } }
3. 检查布局与主题的关联
- 确认布局中的按钮没有手动指定其他覆盖自定义属性的
style; - 确保
AndroidManifest.xml中应用的主题确实是你设置了materialButtonStyle的那个主题。
4. 清理缓存并重新编译
有时候Android Studio的缓存会导致资源无法正确识别,你可以尝试:
- 点击
Build->Clean Project - 然后
Build->Rebuild Project - 重启Android Studio
按照上面的步骤调整后,应该就能正确读取到progressWidth和progressColor这两个自定义属性了。
内容的提问来源于stack exchange,提问作者Mounir
相关产品推荐
相关产品推荐

