171

考虑一下:

样式.xml

<style name="BlueTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <item name="theme_color">@color/theme_color_blue</item>
</style>

attrs.xml

<attr name="theme_color" format="reference" />

颜色.xml

<color name="theme_color_blue">#ff0071d3</color>

所以主题颜色是由主题引用的。如何以编程方式获取 theme_color (参考)?通常我会使用getResources().getColor()但在这种情况下不会使用,因为它被引用了!

4

11 回答 11

326

这应该做的工作:

TypedValue typedValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.theme_color, typedValue, true);
@ColorInt int color = typedValue.data;

还要确保在调用此代码之前将主题应用于您的活动。要么使用:

android:theme="@style/Theme.BlueTheme"

在您的清单或电话中(在您致电之前setContentView(int)):

setTheme(R.style.Theme_BlueTheme)

onCreate().

我已经用您的价值观对其进行了测试,并且效果很好。

于 2013-06-24T14:16:57.467 回答
81

如果您使用的是 kotlin,请添加到已接受的答案中。

@ColorInt
fun Context.getColorFromAttr(
    @AttrRes attrColor: Int,
    typedValue: TypedValue = TypedValue(),
    resolveRefs: Boolean = true
): Int {
    theme.resolveAttribute(attrColor, typedValue, resolveRefs)
    return typedValue.data
}

然后在你的活动中你可以做

textView.setTextColor(getColorFromAttr(R.attr.color))

于 2018-07-27T15:55:04.640 回答
61

我们可以使用 Material Design 库提供的实用程序类:

int color = MaterialColors.getColor(context, R.attr.theme_color, Color.BLACK)

注意:Color.BLACK如果属性提供给 u,则为默认颜色

于 2020-10-24T03:17:07.220 回答
25

这对我有用:

int[] attrs = {R.attr.my_attribute};
TypedArray ta = context.obtainStyledAttributes(attrs);
int color = ta.getResourceId(0, android.R.color.black);
ta.recycle();

如果您想从中获取十六进制字符串:

Integer.toHexString(color)
于 2016-09-07T18:57:03.513 回答
19

2021/January/8

If you want to get color from theme attributes, use the following steps.

Create a variable my_color and store the color from theme attributes as,

val my_color = MaterialColors.getColor(<VIEWOBJECT>, R.attr.<YOUATRRIBUTENAME>)

In place of <VIEWOBJECT>, pass a view object where you want to use the color, (behind the scenes it's just used to get the context as <VIEWOBJECT>.getContext() so that it can access resource i.e theme attribute values) . In place of <YOURATTRIBUTENAME>, use the name of the atrribute that you want to access

Example 1:

If you want want to get color referenced by theme attributes from certain activity. Create a variable that represents a view object on which you want to use the color. Here i have a textView in my activity, i'll just reference its object inside textview variable and pass it to the getColor method and behind the scenes it'll use that object to just get the context, so that it can access theme attribute values

val textview: TextView = findViewById(R.id.mytextview)
val my_color = MaterialColors.getColor(textView, R.attr<YOURATTRIBUTENAME>)

Example 2 :

If you want to get color from theme attributes inside a custom view then just use,

val my_color = MaterialColors.getColor(this, R.attr.<YOUATRRIBUTENAME>)

Inside a custom view this refers to the object of the custom view, which is in fact a view object.

于 2021-01-08T15:09:47.917 回答
13

将此添加到您的 build.gradle(应用程序):

implementation 'androidx.core:core-ktx:1.1.0'

并在代码中的某处添加此扩展功能:

@ColorInt
@SuppressLint("Recycle")
fun Context.themeColor(
    @AttrRes themeAttrId: Int
): Int {
    return obtainStyledAttributes(
        intArrayOf(themeAttrId)
    ).use {
        it.getColor(0, Color.MAGENTA)
    }
}
于 2020-05-06T09:41:48.493 回答
2

如果您想获得多种颜色,可以使用:

int[] attrs = {R.attr.customAttr, android.R.attr.textColorSecondary, 
        android.R.attr.textColorPrimaryInverse};
Resources.Theme theme = context.getTheme();
TypedArray ta = theme.obtainStyledAttributes(attrs);

int[] colors = new int[attrs.length];
for (int i = 0; i < attrs.length; i++) {
    colors[i] = ta.getColor(i, 0);
}

ta.recycle();
于 2018-01-07T15:16:24.803 回答
2

我使用这个 kotlin 扩展

@ColorInt
fun Context.getColorFromAttr( @AttrRes attrColor: Int
): Int {
    val typedArray = theme.obtainStyledAttributes(intArrayOf(attrColor))
    val textColor = typedArray.getColor(0, 0)
    typedArray.recycle()
    return textColor
}

样本

getColorFromAttr(android.R.attr.textColorSecondary)
于 2021-01-25T18:00:21.780 回答
0

对我来说,它只能使用ContextCompattypedValue.resourceId

正如在这个问题中提出的那样:如何以编程方式获取颜色属性的值

TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.colorControlNormal, typedValue, true);
int color = ContextCompat.getColor(this, typedValue.resourceId)
于 2022-01-26T19:07:49.373 回答
0

对于那些正在寻找可绘制参考的人,您应该false使用resolveRefs

theme.resolveAttribute(R.attr.some_drawable, typedValue, **false**);

于 2019-11-01T16:14:14.033 回答
0

这是一个简洁的 Java 实用程序方法,它接受多个属性并返回一个颜色整数数组。:)

/**
 * @param context    Pass the activity context, not the application context
 * @param attrFields The attribute references to be resolved
 * @return int array of color values
 */
@ColorInt
static int[] getColorsFromAttrs(Context context, @AttrRes int... attrFields) {
    int length = attrFields.length;
    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();

    @ColorInt int[] colorValues = new int[length];

    for (int i = 0; i < length; ++i) {
        @AttrRes int attr = attrFields[i];
        theme.resolveAttribute(attr, typedValue, true);
        colorValues[i] = typedValue.data;
    }

    return colorValues;
}
于 2019-05-05T15:18:51.860 回答