Android Resources小研究

研究了一下如何获取各种资源,这里用颜色举例,其他类型没有尝试,但应该大同小异。

我们在 styles.xml
设置 @color/colorPrimary

R.color.colorPrimary
-> Color Int

ContextCompat.getColor(context, R.color.colorPrimary)
-> Color Int

R.attr.colorPrimary
-> Color Int

这里的Context需要带Theme的Context,比如是一个 ContextThemeWrapper
或是Activity/View的Context,不然什么也拿不到。下个例子同理。

@ColorInt
fun Context.themeColor(@AttrRes attrRes: Int): Int {
    val a = obtainStyledAttributes(null, intArrayOf(attrRes))
    try {
        return a.getColor(0, Color.RED)
    } finally {
        a.recycle()
    }
}

然后 context.themeColor(R.attr.colorPrimary)
-> Color Int

R.attr.colorPrimary
-> R.color.colorPrimary
(Color Res)

@ColorRes
fun Context.themeRes(@AttrRes attrRes: Int): Int {
    val a = obtainStyledAttributes(null, intArrayOf(attrRes))
    try {
        return a.getResourceId(0, -1)
    } finally {
        a.recycle()
    }
}

然后 context.themeRes(R.attr.colorPrimary)
-> R.color.colorPrimary

一个更有用的例子是 context.themeRes(R.attr.colorControlActivated)
-> R.color.colorAccent
(通常情况下是这个值)

拦截 View

比如拦截 Button
android:textColor
app:backgroundTint

首先继承 AppCompatButton
MaterialButton

新建 attrs.xml
并塞入:

    
    

然后就可以

context.withStyledAttributes(set, attrs, defStyleAttr, defStyleRes) {
    getColorStateList(R.styleable.Theme_Button_android_textColor)
    getColorStateList(R.styleable.Theme_Button_backgroundTint)
}