以编程方式获取颜色值(主题)

Ser*_*m's 93 android android-theme android-resources

考虑一下:

styles.xml

<style name="BlueTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <item name="theme_color">@color/theme_color_blue</item>
</style>
Run Code Online (Sandbox Code Playgroud)

attrs.xml

<attr name="theme_color" format="reference" />
Run Code Online (Sandbox Code Playgroud)

color.xml

<color name="theme_color_blue">#ff0071d3</color>
Run Code Online (Sandbox Code Playgroud)

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

Ema*_*lin 211

这应该做的工作:

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

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

android:theme="@style/Theme.BlueTheme"
Run Code Online (Sandbox Code Playgroud)

在你的舱单或电话中(在你打电话之前setContentView(int)):

setTheme(R.style.Theme_BlueTheme)
Run Code Online (Sandbox Code Playgroud)

onCreate().

我用你的价值观测试了它,它完美无缺.

  • 如果您不想将主题应用于活动,可以使用主题ID创建`ContextThemeWrapper`,然后从中检索主题. (5认同)
  • 现在已内置。以下内容等效:`MaterialColors.getColor(context, R.attr.colorError, Color.GRAY)` (5认同)
  • 无论如何,使用你的解决方案我得到一个0值颜色(TypedValue {t = 0x0/d = 0x0})...我不使用declare-styleable,只是对颜色的引用 (4认同)

Cha*_*har 42

我们可以使用 Material Design 库提供的工具类:

int color = MaterialColors.getColor(context, R.attr.theme_color, Color.BLACK)
Run Code Online (Sandbox Code Playgroud)

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

  • 最好的答案 (6认同)
  • 这应该是 2021 年公认的答案 (4认同)
  • 当然,推荐使用 MaterialColors 实用程序类。甚至可以基于视图获取主题颜色:`val PrimaryColor = MaterialColors.getColor(view, R.attr.colorPrimary)` (2认同)

Ang*_*lis 21

这对我有用:

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

如果你想从它得到六角形:

Integer.toHexString(color)
Run Code Online (Sandbox Code Playgroud)


Bri*_*6ko 19

要添加到接受的答案,如果您正在使用kotlin.

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

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

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

  • 好的,感谢您的“整合”。我没有用Kotlin,但很有趣。 (2认同)
  • 好吧,它使TypedValue对外界可见。对于颜色,您总是想解析引用声明,所以我有以下内容:@ColorInt fun Context.getThemeColor(@AttrRes attribute:Int)= TypedValue()。let {theme.resolveAttribute(attribute,it,true); it.data}`(此处格式不正确,但是还可以) (2认同)

And*_*mon 12

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

implementation 'androidx.core:core-ktx:1.1.0'
Run Code Online (Sandbox Code Playgroud)

并在代码中的某处添加此扩展函数:

@ColorInt
@SuppressLint("Recycle")
fun Context.themeColor(
    @AttrRes themeAttrId: Int
): Int {
    return obtainStyledAttributes(
        intArrayOf(themeAttrId)
    ).use {
        it.getColor(0, Color.MAGENTA)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我想从“android.R.attr.textColorSecondary”参考中获取颜色,只有这个解决方案有效。谢谢。 (3认同)

ΞXP*_*ACE 10

2021/January/8

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

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

val my_color = MaterialColors.getColor(<VIEWOBJECT>, R.attr.<YOUATRRIBUTENAME>)
Run Code Online (Sandbox Code Playgroud)

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

示例 1:

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

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

示例 2:

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

val my_color = MaterialColors.getColor(this, R.attr.<YOUATRRIBUTENAME>)
Run Code Online (Sandbox Code Playgroud)

自定义视图里面是this指自定义视图的对象,其实就是一个视图对象。