getColor(int id)在Android 6.0棉花糖(API 23)上已弃用


717

Resources.getColor(int id)方法已被弃用。

@ColorInt
@Deprecated
public int getColor(@ColorRes int id) throws NotFoundException {
    return getColor(id, null);
}

我该怎么办?


26
使用ContextCompat.getColor(context,R.color.color_name)
Ashokchakravarthi Nagarajan

使用上述方法:getColor(context,R.color.your_color); 目前尚不清楚如何获得“上下文”。仅将上下文放在我的情况下(android studio 3.2)不能工作。我觉得这很适合我。.setTextColor(Color.RED)。
哈利

Answers:


1347

从Android支持库23开始, 已将
新的getColor()方法添加到ContextCompat

其来自官方JavaDoc的描述:

返回与特定资源ID关联的颜色

从M开始,将为指定的Context主题设置返回的颜色样式。


因此,只需致电

ContextCompat.getColor(context, R.color.your_color);


您可以ContextCompat.getColor() 在GitHub上检查源代码


1
这看起来像解决方案,但是当出现错误“应该在此处传递解析的颜色而不是资源ID”时,我们应该怎么办?据我所知,可能是因为Lint无法识别支持库的新API,所以也许只添加注释@SuppressWarnings(“ ResourceAsColor”)是可行的方法?我不太喜欢。
Stan

1
@Stan,您好,能否为代码片段提供触发“ ResourceAsColor” Lint的方法调用?
Araks

“ int颜色= ContextCompat.getColor(this,R.color.orange);” 然后“ span = new ForegroundColorSpan(color);”。带红色下划线的单词是“颜色”,我将其传递给“ new ForegroundColorSpan()”。
Stan

1
@MonicaLabbao哦...抱歉,我误解了您的评论!:)
araks'Aug

3
ContextCompatApi23此标记错误使您无法参考ContextCompat
Webserveis

498

tl; dr:

ContextCompat.getColor(context, R.color.my_color)

说明:

您将需要使用ContextCompat.getColor(),它是Support V4库的一部分(它将适用于所有以前的API)。

ContextCompat.getColor(context, R.color.my_color)

如果尚未使用支持库,则需要将以下行添加到dependencies应用程序内部的数组中build.gradle(注意:如果您已经使用了appcompat(V7)库,则这是可选的):

compile 'com.android.support:support-v4:23.0.0' # or any version above

如果您关心主题,则文档中指定:

从M开始,将为指定的Context主题设置返回的颜色样式


4
这应该被选为正确答案。因为在Android Docs的给定链接中,它说“ 开始于M,返回的颜色将为指定的Context主题设置样式。
Bug发生

1
编译'com.android.support:appcompat-v7:23.0.1'
G ^ O'Rilla

@G O'Rilla正如您在文档中所看到的,ContextCompat该类来自SupportV4。AppcompatV7也可以使用,因为它依赖于SupportV4。如他们在支持库文档中所说,This library depends on the v4 Support Library. If you are using Ant or Eclipse, make sure you include the v4 Support Library as part of this library's classpath.。因此,不要给出AppcompatV7答案是有道理的。
梅尔文2015年

1
感谢@Melvin,这是我使用的示例:int colorTwitterBlue = ContextCompat.getColor(this,R.color.color_twitter_blue); composeTweetAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(colorTwitterBlue); composeTweetAlertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(colorTwitterBlue);
Lara Ruffle Coles

1
@梅尔文 这到底是什么意思?“颜色将被设置为指定的上下文主题”。听起来像是可以根据主题为同一颜色id定义不同的颜色。究竟如何完成?
罗伯托·库巴(RobertoCuba)'17

46

我不想只为getColor包括支持库,所以我正在使用类似

public static int getColorWrapper(Context context, int id) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return context.getColor(id);
    } else {
        //noinspection deprecation
        return context.getResources().getColor(id);
    }
}

我猜代码应该可以正常工作,并且弃用的getColorAPI不能从<23消失。

这就是我在Kotlin中使用的:

/**
 * Returns a color associated with a particular resource ID.
 *
 * Wrapper around the deprecated [Resources.getColor][android.content.res.Resources.getColor].
 */
@Suppress("DEPRECATION")
@ColorInt
fun getColorHelper(context: Context, @ColorRes id: Int) =
    if (Build.VERSION.SDK_INT >= 23) context.getColor(id) else context.resources.getColor(id);

4
查看源代码,这正是支持库的工作方式。我的目标API> = 21,所以我不想为这几行添加一个完整的jar。请注意,您可以通过在已弃用的调用上方添加“ // noinspection弃用”来抑制Android Studio中的警告。并使用活动上下文,而不是应用程序上下文,否则您可能会丢失主题信息。
personne3000

2
这应该是正确的答案,尽管支持库可以作为将来的证明,但我确实同意,如果这是包括支持库的唯一原因,那么最好包括以下几行。
anthonymonori

30

在Android Marshmallow中,不赞成使用许多方法。

例如,获取颜色

ContextCompat.getColor(context, R.color.color_name);

也可用于绘画

ContextCompat.getDrawable(context, R.drawable.drawble_name);

3
可变上下文来自哪里?我必须初始化吗?我无法正常工作。在我看来,安德鲁因德(Androind)任重而道远。它让我大吃一惊,我为从xml资源中获取af颜色付出了很多努力!!哇
ColdTuna

29

对于所有Kotlin用户:

context?.let {
    val color = ContextCompat.getColor(it, R.color.colorPrimary)
    // ...
}

其实应该是val color = ContextCompat.getColor(context, R.color.colorPrimary)。变量“ it”可以是任何东西,但必须是Context
Scott Biggs

it在这种情况下是context,因为我context?.let {用来检查的值context是否不为null。该函数getColor()仅接受非空上下文。在这里阅读更多有关let如何使用它的信息:kotlinlang.org/docs/reference/scope-functions.html#let
Paul Spiesberger

4

在Kotlin的RecyclerView中

inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(t: YourObject, listener: OnItemClickListener.YourObjectListener) = with(itemView) {
        textViewcolor.setTextColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary))
        textViewcolor.text = t.name
    }
}

1

使用getColor(Resources, int, Theme)的方法ResourcesCompat从Android支持库。

int white = new ResourcesCompat().getColor(getResources(), R.color.white, null);

我觉得它更好地反映比你的问题getColor(Context, int)ContextCompat,因为你问Resources。在API级别23之前,将不会应用主题,并且该方法将调用到,getColor(int)但您不会收到不建议使用的警告。主题也可能是null


1
如果将null作为Theme参数传递,则将不为当前主题设置返回颜色的样式。因此,这可能是不正确的。
2015年


1

如果您当前的分钟。API级别为23,您可以getColor()像通过以下方式简单地使用来获取字符串资源getString()

//example
textView.setTextColor(getColor(R.color.green));
// if `Context` is not available, use with context.getColor()

您可以限制API级别低于23:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

但为简单起见,您可以像下面这样作为接受的答案:

textView.setTextColor(ContextCompat.getColor(context, R.color.green))

来自资源

来自ContextCompat AndroidX

来自ContextCompat支持


0

我也感到沮丧。我的需求非常简单。我只想要资源中的ARGB颜色,所以我写了一个简单的静态方法。

protected static int getARGBColor(Context c, int resId)
        throws Resources.NotFoundException {

    TypedValue color = new TypedValue();
    try {
        c.getResources().getValue(resId, color, true);
    }
    catch (Resources.NotFoundException e) {
        throw(new Resources.NotFoundException(
                  String.format("Failed to find color for resourse id 0x%08x",
                                resId)));
    }
    if (color.type != TYPE_INT_COLOR_ARGB8) {
        throw(new Resources.NotFoundException(
                  String.format(
                      "Resourse id 0x%08x is of type 0x%02d. Expected TYPE_INT_COLOR_ARGB8",
                      resId, color.type))
        );
    }
    return color.data;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.