如何通过编程获取颜色属性值?resolveAttribute取值异常问题
编程获取Android颜色属性值的方法 & 你遇到的resolveAttribute()结果问题解答
嘿,我来帮你理清这两个问题~
一、如何通过编程方式获取颜色属性的值?
要获取主题里像?attr/colorControlNormal这类颜色属性的值,核心是用TypedValue配合主题的resolveAttribute()方法,但得注意属性的存储类型——有些属性直接存颜色值,有些是指向颜色资源的引用,具体操作分这几步:
- 先创建一个
TypedValue对象,用来承接解析后的属性数据 - 调用
getTheme().resolveAttribute(),把目标属性ID、TypedValue对象和true(强制解析)传进去 - 根据
TypedValue的类型处理结果:- 如果
typedValue.type等于TypedValue.TYPE_INT_COLOR_ARGB8,那typedValue.data就是直接可用的ARGB颜色值 - 如果是
TypedValue.TYPE_REFERENCE,说明这个属性指向的是一个颜色资源ID,得再用ContextCompat.getColor()或者getResources().getColor()(API 23+)去解析这个ID,才能拿到实际颜色
- 如果
给你个完整的示例代码:
TypedValue typedValue = new TypedValue(); if (getTheme().resolveAttribute(R.attr.colorControlNormal, typedValue, true)) { int finalColor; if (typedValue.type == TypedValue.TYPE_INT_COLOR_ARGB8) { // 属性直接存储颜色值 finalColor = typedValue.data; } else { // 属性是资源引用,需要二次解析 finalColor = ContextCompat.getColor(this, typedValue.data); } // 这里finalColor就是你要的实际颜色值啦 }
二、为什么你用resolveAttribute()得到的是236?
你拿到的236根本不是颜色值,而是颜色资源的引用ID(准确说是资源的索引编号)。因为?attr/colorControlNormal在你的主题配置里,并没有直接写死颜色值,而是指向了某个@color/xxx资源。
这时候typedValue.type应该是TypedValue.TYPE_REFERENCE,所以typedValue.data是资源ID,你得再走一步解析才能拿到真实颜色。修改你的代码试试:
TypedValue typedValue = new TypedValue(); getTheme().resolveAttribute(R.attr.colorControlNormal, typedValue, true); int color; if (typedValue.type == TypedValue.TYPE_REFERENCE) { // 解析资源ID得到实际颜色 color = ContextCompat.getColor(this, typedValue.data); } else { color = typedValue.data; } // 现在color就是正确的ARGB颜色值了
至于XML里直接用?attr/colorControlNormal能正常显示,是因为系统在渲染布局时自动帮你完成了这个资源解析的步骤,不用你手动处理~
内容的提问来源于stack exchange,提问作者Ωmega
相关产品推荐
相关产品推荐

