当它作为参考(主题)时以编程方式获取颜色值

时间:2013-06-24 14:12:02

标签: android android-resources android-theme

考虑一下:

styles.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" />

color.xml

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

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

10 个答案:

答案 0 :(得分:182)

这应该做的工作:

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

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

android:theme="@style/Theme.BlueTheme"
在您的清单或通话中

(在致电setContentView(int)之前):

setTheme(R.style.Theme_BlueTheme)
onCreate()中的

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

答案 1 :(得分:17)

这对我有用:

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)

答案 2 :(得分:12)

要添加到接受的答案(如果您使用的是kotlin)。

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))

答案 3 :(得分:9)

2021/January/8

如果您想从主题属性中获取颜色,请使用以下步骤。

创建一个变量 my_color 并将主题属性的颜色存储为,

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

代替<VIEWOBJECT>,传递一个你想要使用颜色的视图对象,(在幕后它只是用来获取上下文为<VIEWOBJECT>.getContext(),以便它可以访问资源即主题属性值)。代替 <YOURATTRIBUTENAME>,使用您要访问的属性的名称

示例 1:

如果您想从某些活动中获取主题属性引用的颜色。 创建一个变量,该变量表示要在其上使用颜色的视图对象。 这里我的 Activity 中有一个 textView,我将在 textview 变量中引用它的对象并将其传递给 getColor 方法,在幕后它将使用该对象来获取上下文,以便它可以访问主题属性值

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

示例 2:

如果你想从自定义视图中的主题属性中获取颜色,那么只需使用,

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

在自定义视图内部 this 指的是自定义视图的对象,它实际上是一个视图对象。

答案 4 :(得分:5)

将此添加到您的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)
    }
}

答案 5 :(得分: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();

答案 6 :(得分:2)

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

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

注意:如果属性提供给u

,则Color.BLACK是默认颜色

答案 7 :(得分: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)

答案 8 :(得分: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;
}

答案 9 :(得分:0)

对于那些希望参考可绘制对象的人,您应该在false中使用resolveRefs

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