gpt4 book ai didi

android - `theme`中的 `context.getColor`有什么用?

转载 作者:太空宇宙 更新时间:2023-11-03 12:45:12 27 4
gpt4 key购买 nike

背景

从API 23开始,不建议使用获取颜色 getColor (仅为其提供资源ID)的小方法:

enter image description here

相反,我们被告知也要使用包含Theme参数的方法:

This method was deprecated in API level 23. Use getColor(int, Theme) instead.



https://developer.android.com/reference/android/content/res/Resources.html#getColor(int,android.content.res.Resources.Theme)

问题

The docs 不用多说 theme:

enter image description here

https://developer.android.com/reference/android/content/res/Resources.html#getColor(int,android.content.res.Resources.Theme)

我发现了什么

通过Internet搜索,我能找到的就是我们可以使用支持库来获取颜色:
ContextCompat.getColor(context, R.color.color_name);

这有点不可思议,因为在幕后,似乎并没有对主题做任何事情。这是它的代码:
@ColorInt
public static final int getColor(@NonNull Context context, @ColorRes int id) {
if (Build.VERSION.SDK_INT >= 23) {
return context.getColor(id);
} else {
return context.getResources().getColor(id);
}
}

查看Context.getColor,我可以看到:

enter image description here

在我看来,它使用的是 Activity 的主题?

问题
  • “主题”参数的目的是什么?
  • 如何使用?是否有关于它的样本/教程/文章?
  • 为什么仍然不建议使用该函数?对我来说似乎仍然可以安全使用...
  • 支持库功能的用途是什么?与不赞成使用的功能有何不同?
  • 最佳答案

    tl;博士

  • 如果,则您的最小SDK为23 ,则不需要compat API来获取颜色。
  • 如果使用,则不要使用颜色为的主题属性引用,也不要计划更改,请像以前一样使用Context.getResources().getColor(int)getColorStateList(int)。已将其标记为已弃用,但从功能上来说还可以。
  • 如果您想使用,则仅在API 23+上以彩色使用主题属性引用,请使用ContextCompat.getColorStateList(Context, int),即
  • 如果使用,则使用AppCompat,并且希望能够在所有版本的Android 上使用主题属性引用,请使用AppCompatResources.getColorStateList(Context, int)


  • 从API 23开始 ColorStateList可以包含主题属性引用,自API 21开始, Drawable允许这样做。

    主题属性通常用在通过 getColorStateList方法获得的颜色状态列表中,而不是 getColor,因此从现在开始我将使用它。提到的大多数内容都适用于这两种变体。

    例子:

    res/color/my_csl.xml
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="?attr/colorControlHighlight" android:alpha="?android:disabledAlpha"/>
    <item android:color="?attr/colorControlHighlight"/>
    </selector>

    What's the purpose of the 'theme' parameter?



    解析主题属性需要主题。资源本身不知道任何主题。主题由上下文提供。
    context.getColorStateList(R.color.my_csl);

    本质上是
    context.getResources().getColorStateList(R.color.my_csl, context.getTheme());

    这两种方法都是公共(public)API的一部分,因此它们都被反向移植:
    ContextCompat.getColorStateList(context, R.color.my_csl);
    ResourcesCompat.getColorStateList(context.getResources(), R.color.my_csl, context.getTheme());

    How is it used?



    通常,它就是这样简单:
    final int myColor = ContextCompat.getColorStateList(context, R.color.my_csl);

    如果您使用AppCompat,则最好使用另一种选择:
    final int myColor = AppCompatResources.getColorStateList(context, R.color.my_csl);

    这是这两个选项之间的比较:
  • ContextCompat.getColorStateList
  • 只需要support-compat支持库
  • 仅向后移植API-尝试在API 23以下解析主题属性时会崩溃
  • AppCompatResources.getColorStateList
  • 需要完整的appcompat-v7支持库
  • Backports功能-即使在API 23之下,它也将尊重上下文主题
  • ResourcesCompat.getColorStateList(int, Theme)Resources.getColorStateList(int, Theme)的API(非功能性)反向端口,由API 23+上的 Context.getColorStateList(int)内部使用。在日常使用中,您将不需要此方法。

    Why was the function deprecated anyway? It still seems safe to use for me...



    不建议使用该方法,以将开发人员从不了解主题的版本迁移到该方法的主题感知版本。

    只要您使用主题感知方法来获取没有主题属性引用的颜色,该方法仍然非常安全,例如:

    res/values/colors.xml
    <resources>
    <color name="my_cint">#f00</color>
    </resources>

    可以通过安全地获得
    context.getResources().getColor(R.color.my_cint);

    What's the use of the support library function?


    ContextCompat.getColorStateList(context, R.color.my_csl);

    从字面上是这个
    public static final ColorStateList getColorStateList(Context context, @ColorRes int id) {
    if (Build.VERSION.SDK_INT >= 23) {
    return context.getColorStateList(id);
    } else {
    return context.getResources().getColorStateList(id);
    }
    }

    该方法存在,因此您不必在所有地方都编写if-else。而已。

    在API 23+上,它可以使用上下文主题。在API 23以下,它会退回到无法解析主题属性的旧版本。
    ResourcesCompat.getColorStateList(int, Theme)的外观和工作方式类似,它会忽略API 23下的主题属性(使用它们时出现崩溃)。
    AppCompatResources.getColorStateList(Context, int)不会崩溃,并且可以在所有版本的Android上正确解析主题属性。

    What about ResourcesCompat#getColorStateList?



    您通常不需要此方法。

    这是抽象层。它告诉您解决颜色不需要任何上帝对象,任何 ContextResources足以解决颜色。但为了使 Resources能够解析主题属性,您需要提供一个 Theme。可以从 Theme获得 Context的事实与 Resources无关。 Resources不会透露或关心它本身是否来自某些 Context.getResources()

    Can you [...] update about getColor too?


    getColor将解决
  • <color>资源作为颜色整数
  • <selector>颜色状态列表资源作为其默认颜色
  • 的颜色整数
    getColorStateList将解决
  • <color>资源作为ColorStateList的一种颜色
  • <selector> CSL资源为带有指定颜色的ColorStateList

  • 使用使用者API所需的一种。

    没有 AppCompatResources.getColor(Context, int),因为将颜色资源定义为主题属性引用没有什么意义。如果需要,此 AppCompatResources.getColorStateList(Context, int).getDefaultColor()是等效的功能。

    之所以存在 ContextCompat.getColor(Context, int)ResourcesCompat.getColor(Resources, int, Theme),是因为它们镜像了框架API。如上所述,它们的实际用途值得商bat。

    我建议阅读下面的讨论,以掌握一些难以捉摸的细微差别。

    关于android - `theme`中的 `context.getColor`有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47962074/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com