从API 23开始,不推荐使用获取资源 getColor (仅提供资源ID)的小方法:
相反,我们被告知要使用包含Theme
参数的方法:
此方法在API级别23中已弃用。使用getColor(int,Theme) 代替。
https://developer.android.com/reference/android/content/res/Resources.html#getColor(int,android.content.res.Resources.Theme)
The docs 对theme
:
https://developer.android.com/reference/android/content/res/Resources.html#getColor(int,android.content.res.Resources.Theme)
通过互联网搜索,我能找到的是我们可以使用支持库来获取颜色:
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,我可以看到:
所以在我看来它使用了活动的主题?
'主题的目的是什么?参数?
如何使用?有没有关于它的样本/教程/文章?
为什么函数不赞成?它对我来说似乎仍然安全......
支持库功能的用途是什么?使用已弃用的功能有何不同?
答案 0 :(得分:5)
<强> TL;博士强>
Context.getResources().getColor(int)
或getColorStateList(int)
。它被标记为已弃用,但在功能上它没关系。ContextCompat.getColorStateList(Context, int)
。AppCompatResources.getColorStateList(Context, int)
。启动API 23 ColorStateList
可以包含主题属性引用,这与自API 21以来Drawable
中允许的内容相同。
主题属性主要用于通过getColorStateList
方法而不是getColor
获得的颜色状态列表,因此我将从现在开始使用它。所提到的大多数都适用于这两种变体。
示例:
<强> RES /颜色/ 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>
'主题'参数的目的是什么?
主题是解析主题属性所必需的。资源本身并不知道任何主题。主题由上下文提供。
context.getColorStateList(R.color.my_csl);
本质上是
的捷径context.getResources().getColorStateList(R.color.my_csl, context.getTheme());
这两种方法都是公共API的一部分,因此它们都被反向移植:
ContextCompat.getColorStateList(context, R.color.my_csl);
ResourcesCompat.getColorStateList(context.getResources(), R.color.my_csl, context.getTheme());
如何使用?
通常它就像这样简单:
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
支持库 AppCompatResources.getColorStateList
appcompat-v7
支持库 ResourcesCompat.getColorStateList(int, Theme)
是Resources.getColorStateList(int, Theme)
的API(非功能性)后端,Context.getColorStateList(int)
在API 23+上内部使用。在日常使用中,您将不需要这种方法。
为什么函数不赞成?它对我来说似乎仍然安全......
该方法已弃用,可将开发人员从不知道主题的版本迁移到方法的主题感知版本。
主题 - 不知道方法仍然可以非常安全地使用,只要您使用它来获取没有主题属性引用的颜色,例如:
<强> RES /值/ colors.xml 强>
<resources>
<color name="my_cint">#f00</color>
</resources>
可以安全地获得
context.getResources().getColor(R.color.my_cint);
支持库功能的用途是什么?
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版本的主题属性。
ResourcesCompat#getColorStateList
怎么样?
您通常不需要这种方法。
这是一个抽象层。它告诉你,要解决一种颜色你不需要任何神对象,任何Context
。 Resources
足以解析颜色。但是Resources
能够解析您需要提供Theme
的主题属性。可以从Theme
获取Context
的事实与Resources
无关。 Resources
并未透露或关注它本身来自某些Context.getResources()
。
你能[...]更新
getColor
吗?
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。如上所述,它们的实用性是值得商榷的。
我建议阅读下面的讨论,以掌握一些难以捉摸的微妙差异。
答案 1 :(得分:0)
我经常使用片段,并且通过玩耍找到了这些片段。 首先按如下所示设置上下文变量:
self.setWindowFlags(_qt.FramelessWindowHint)
然后实例化上下文,如下所示:
private lateinit var contextX: Context
然后使用contextX将颜色分配给视图
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
contextX=requireContext() ......
这很好。所需的导入应由系统自动生成。
导入此功能后,应自动加载它们,但在选择提示时要小心。
binding.veeGroupId.setBackgroundColor(getColor(contextX,R.color.yellow_light))