Android 如何通过代码获取自定义color类型attr属性并设置给TextView
问题根因
- 自定义属性
uiColorPrimaryRipple未在当前Context关联的主题中赋值:XML中用?attr/xxx能生效是因为XML解析默认使用所属Activity的主题配置,代码获取时如果主题中没有对应属性的赋值,就会返回你设置的默认值0(透明色),看起来像获取失败。 - 若调用方法时使用的是ApplicationContext,默认不会加载Activity层面声明的主题属性,也会导致获取失败。
- 原方法默认 fallback 值设为0(完全透明),获取失败时没有兜底的可见色值,无法直观判断是否获取异常。
修复步骤
- 首先确认自定义属性已在使用的主题中赋值,在你的
themes.xml/styles.xml的AppTheme(或你当前页面使用的主题)中添加如下配置:
<item name="uiColorPrimaryRipple">@color/你要设置的实际颜色值</item>
- 优化属性获取方法,显式使用Context的主题获取,调整兜底默认值,移除无用的可变参数:
fun Context.fetchAttrColor(@AttrRes attr: Int, defaultColor: Int = Color.BLACK): Int { val typedArray = theme.obtainStyledAttributes(intArrayOf(attr)) val resultColor = typedArray.getColor(0, defaultColor) typedArray.recycle() return resultColor }
- 调用时使用控件本身的Context获取属性,再赋值给TextView:
val rippleColor = textView.context.fetchAttrColor(R.attr.uiColorPrimaryRipple) textView.setTextColor(rippleColor)
注意事项
- 禁止使用ApplicationContext调用该方法,ApplicationContext的主题不会包含Activity层面自定义的属性值
- 如果应用有动态切换主题的逻辑,切换主题后需要重新调用该方法获取对应主题下的颜色
- 如果你的属性format同时支持color和reference类型,可额外添加类型判断逻辑,避免类型转换异常
内容的提问来源于stack exchange,提问作者montassar zarroug
相关产品推荐
相关产品推荐

