在Android 6.0 Marshmallow (API 23)中,getColor(int id)已经被弃用。

788

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

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

我该怎么办?


38
使用ContextCompat.getColor(context, R.color.color_name)获取颜色。 - Ashokchakravarthi Nagarajan
通过上面提到的方法:getColor(context, R.color.your_color); 不清楚如何获取“context”。在我的情况下,仅仅把context放在那里是行不通的,因为我使用的是Android Studio 3.2。我发现这对我有用:.setTextColor(Color.RED)。 - Harry
14个回答

1461

从 Android Support Library 23 开始,
一个新的 getColor() 方法已经添加到 ContextCompat 中。

官方 JavaDoc 中对其进行了描述:

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

从 M 开始,返回的颜色将基于指定上下文的主题进行样式化。


因此,只需调用:

ContextCompat.getColor(context, R.color.your_color);
你可以在GitHub上检查ContextCompat.getColor()源代码

1
这看起来像是解决方案,但当我们遇到错误“应该传递已解析的颜色而不是资源ID”时,我们应该怎么办?据我所知,这可能是因为Lint无法识别Support Library的新API,所以也许只需添加注释@SuppressWarnings("ResourceAsColor")就可以了?虽然我不太喜欢这种方法。 - Stan
1
嗨 @Stan,你能提供一个触发“ResourceAsColor” Lint的方法调用的代码片段吗? - araks
1
@MonicaLabbao 哦...抱歉,我误解了你的评论! :) - araks
3
ContextCompatApi23这个标记错误意味着你引用了ContextCompat,应该使用它的API Level 23以上的版本。 - Codelaby
1
我不明白“主题”有什么用处。有没有示例? - android developer
显示剩余15条评论

516

简而言之:

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

说明:

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

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

如果你还没有使用支持库,需要在你的应用build.gradle文件中的dependencies数组中添加以下行(注意:如果你已经使用了appcompat(V7)库则是可选的):
compile 'com.android.support:support-v4:23.0.0' # or any version above

如果您关注主题,文档指定:

从 M 开始,返回的颜色将针对指定上下文的主题进行样式设置


4
应该选择这个作为正确答案。因为在提供的Android文档链接中,它说:“从M开始,返回的颜色将针对指定上下文主题进行样式设置。” - Bugs Happen
1
编译 'com.android.support:appcompat-v7:23.0.1' - G O'Rilla
@G O'Rilla 正如文档中所述,ContextCompat 类来自 SupportV4。AppcompatV7 也可以使用,因为它依赖于 SupportV4。正如 Support Library documentation 中所说,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 放入其中是有道理的。 - Melvin
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
@Melvin。“颜色将根据指定上下文的主题进行样式化”这句话具体是什么意思?听起来好像可以根据不同的主题为相同的颜色ID定义不同的颜色。这是如何实现的呢? - RobertoCuba
显示剩余2条评论

51

我不想仅仅为了getColor引入Support库,所以我正在使用类似以下的内容

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

我猜代码应该可以正常工作,而被弃用的getColor在API < 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 deprecation”来抑制Android Studio中的警告。并且要使用Activity上下文,而不是应用程序上下文,否则可能会丢失主题信息。 - personne3000
2
这应该是正确的答案,尽管支持库可能是更具未来性的选择,但我同意如果这是你包含支持库的唯一原因,最好包含这几行代码就足够了。 - anthonymonori

31

对于所有的 Kotlin 用户:

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

实际上应该是 val color = ContextCompat.getColor(context, R.color.colorPrimary)。变量 "it" 可以是任何东西,但它需要是一个 __Context__。 - SMBiggs
在这种情况下,itcontext,因为我使用 context?.let { 来检查 context 是否为非空。函数 getColor() 只接受非空的 context。在此处阅读有关 let 及其用法的更多信息:https://kotlinlang.org/docs/reference/scope-functions.html#let - Paul Spiesberger

31

在Android Marshmallow中,许多方法已经被弃用。

例如,要获取颜色,请使用

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

也可以使用以下代码获取可绘制对象:

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

3
变量"context"从哪里来?我需要初始化它吗?我无法让它工作。对我来说,似乎Androind还有很长的路要走;我真的很惊讶,为了从XML资源中获取一种颜色而苦苦挣扎!哇 - Caio Mar

9
在 Kotlin 中,您可以这样做:
ContextCompat.getColor(requireContext(), R.color.stage_hls_fallback_snackbar)

如果您在调用函数的位置可以访问requireContext(),那么请继续使用它。我在尝试时遇到了一个错误。

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

7

在活动中使用了ContextCompat。

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

在适配器中

private Context context;


context.getResources().getColor()

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

2
最好的替代方法是使用ContextCompat.getColorResourcesCompat.getColor。我编写了一些扩展函数,方便快速迁移:
@ColorInt
fun Context.getColorCompat(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)

@ColorInt
fun Fragment.getColorCompat(@ColorRes colorRes: Int) = activity!!.getColorCompat(colorRes)

@ColorInt
fun Resources.getColorCompat(@ColorRes colorRes: Int) = ResourcesCompat.getColor(this, colorRes, null)

2

如果您当前的最小API级别为23,则可以像使用getString()获取字符串资源一样,简单地使用getColor()

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

来自资源(Resources)

来自AndroidX的ContextCompat

来自支持(ContextCompat Support)的ContextCompat。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接