如果您通过以下的代码来获取定义的颜色值
context.getResources().getColor(R.color.some_color_resource_id);
在 Android Studio 中会有一个 lint 警告,提示您 Resources#getColor(int) 在 Marshmallow 中被废弃了,建议使用主题可知的 Resources#getColor(int, Theme) 函数。 为了避免该警告,则可以使用 ContextCompat:
ContextCompat.getColor(context, R.color.some_color_resource_id);
该函数的实现是这样的:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return context.getResources().getColor(id, context.getTheme()); } else { return context.getResources().getColor(id); }
看起来很简单。但是为什么会这样呢? 为什么会开始使用带主题的函数而废弃之前的函数呢?
Resources#getColor(int) & Resources#getColorStateList(int) 的问题
首先来看看这两个被废弃的函数是干啥的:
– Resources#getColor(int) 返回一个资源 id 对应的颜色值,如果该资源为 ColorStateList 则返回 ColorStateList 的默认颜色值
– Resources#getColorStateList(int) 返回对应的 ColorStateList
上面的代码在什么情况下会破坏我的代码呢?
要理解为何废弃这两个函数,来看个 ColorStateList 的例子。 当在 TextView 中使用自定义的 ColorStateList 的时候, TextView 不可用状态和可用状态的文字颜色分别使用 R.attr.colorAccent 和 R.attr.colorPrimary 表示。
XHTML
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="?attr/colorAccent" android:state_enabled="false"/> <item android:color="?attr/colorPrimary"/> </selector>
现在如果您通过如下的代码来获取这个ColorStateList
ColorStateList csl = context.getResources().getColorStateList(R.color.button_text_csl);
上面的代码会抛出一个异常(查看logcat 可以看到如下的信息)
W/Resources: ColorStateList color/button_text_csl has unresolved theme attributes! Consider using Resources.getColorStateList(int, Theme) or Context.getColorStateList(int) at android.content.res.Resources.getColorStateList(Resources.java:1011) ...
哪里出错了呢?
问题的根源在于 Resources 对象并没有和一个 Theme 对象关联,当使用 R.attr.colorAccent 和 R.attr.colorPrimary 指代颜色的时候,在代码中通过上面的函数解析的时候没有指定对应的 Theme导致无法解析出结果。 所以在 Marshmallow 中添加了 ColorStateList 对 Theme 的支持并且添加了这两个新的函数:Resources#getColor(int, Theme) 和 Resources#getColorStateList(int, Theme),并使用 Theme 参数来解析里面的 attributes 属性。
在新版本的 Support 库中也有对应的实现,分别位于 ResourcesCompat 和 ContextCompat 类中。
如何解决该问题呢?
使用 AppCompat v24+ 版本可以很容易的解决该问题。
ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.button_text_csl);
在 23+ 版本上直接使用系统的函数,在之前的版本上 AppCompat 自己解析这些 xml 文件从里面提取 attr 属性指代的数值。 AppCompat 同时还支持 ColorStateList 新的 android:alpha 属性。
Resources#getDrawable(int) 的问题
Resources#getDrawable(int) 和前面的两个函数的问题是类似的。 在 Lollipop 之前的版本中无法支持 Theme attr 。
为啥我这样用也没有出现异常呢?
异常并不总是会出现。
VectorDrawableCompat 和 AnimatedVectorDrawableCompat 类中添加了和 AppCompatResources 类类似的功能。比如在 矢量图中你可以使用 ?attr/colorControlNormal 来设置矢量图的颜色,VectorDrawableCompat 会自动完成解析该 属性的工作:
XHTML
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0" android:tint="?attr/colorControlNormal"> <path android:pathData="..." android:fillColor="@android:color/white"/> </vector>
小测试
下面使用一个小测试来回顾一下前面介绍的内容。 假设有下面一个 ColorStateList:
XHTML
<!-- res/colors/button_text_csl.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="?attr/colorAccent" android:state_enabled="false"/> <item android:color="?attr/colorPrimary"/> </selector>
在应用中定义了如下的 Theme:
XHTML
<!-- res/values/themes.xml --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/vanillared500</item> <item name="colorPrimaryDark">@color/vanillared700</item> <item name="colorAccent">@color/googgreen500</item> </style> <style name="CustomButtonTheme" parent="ThemeOverlay.AppCompat.Light"> <item name="colorPrimary">@color/brown500</item> <item name="colorAccent">@color/yellow900</item> </style>
在代码中有如下的函数用来解析颜色值并在代码中创建 ColorStateList:
@ColorInt private static int getThemeAttrColor(Context context, @AttrRes int colorAttr) { TypedArray array = context.obtainStyledAttributes(null, new int[]{colorAttr}); try { return array.getColor(0, 0); } finally { array.recycle(); } } private static ColorStateList createColorStateList(Context context) { return new ColorStateList( new int[][]{ new int[]{-android.R.attr.state_enabled}, // Disabled state. StateSet.WILD_CARD, // Enabled state. }, new int[]{ getThemeAttrColor(context, R.attr.colorAccent), // Disabled state. getThemeAttrColor(context, R.attr.colorPrimary), // Enabled state. }); }
看看是否能猜出在 API 19 和 API 23 版本上文字禁用状态和正常状态的颜色,实现代码如下(5和8的情况,在TextView xml 中指定了 android:theme=”@style/CustomButtonTheme” ):
Resources res = ctx.getResources(); // (1) int deprecatedTextColor = res.getColor(R.color.button_text_csl); button1.setTextColor(deprecatedTextColor); // (2) ColorStateList deprecatedTextCsl = res.getColorStateList(R.color.button_text_csl); button2.setTextColor(deprecatedTextCsl); // (3) int textColorXml = AppCompatResources.getColorStateList(ctx, R.color.button_text_csl).getDefaultColor(); button3.setTextColor(textColorXml); // (4) ColorStateList textCslXml = AppCompatResources.getColorStateList(ctx, R.color.button_text_csl); button4.setTextColor(textCslXml); // (5) Context themedCtx = button5.getContext(); ColorStateList textCslXmlWithCustomTheme = AppCompatResources.getColorStateList(themedCtx, R.color.button_text_csl); button5.setTextColor(textCslXmlWithCustomTheme); // (6) int textColorJava = getThemeAttrColor(ctx, R.attr.colorPrimary); button6.setTextColor(textColorJava); // (7) ColorStateList textCslJava = createColorStateList(ctx); button7.setTextColor(textCslJava); // (8) Context themedCtx = button8.getContext(); ColorStateList textCslJavaWithCustomTheme = createColorStateList(themedCtx); button8.setTextColor(textCslJavaWithCustomTheme);
下面是对应的实现截图:
总结
以上就是关于分析Android多主题颜色的相关问题的全部内容,希望本文的内容对大家开发Android能有所帮助。
我有一个XML文件,它用颜色和图案定义了应用程序的UI,但它们似乎都被themes.XML中的主题覆盖了。如何禁用此功能? 示例: 此按钮: 应该具有黑色背景,因为它在round_button.xml中定义: 然而,它是紫色,颜色来自主题: 如何覆盖此主题?
配置插件 暂时只支持配合vux-loader使用。 注意的是主题文件不能引入其他less文件,只能为简单变量列表。 请配置vux-loader的less-theme插件,指定用以覆盖的less文件路径: { name: 'less-theme', path: 'src/styles/theme.less' // 相对项目根目录路径 } 可配置颜色 源码地址:https://github.
Color themes let you modify VS Code's background, text and language syntax colorization to suit your preferences and work environment. VS Code supports light, dark and high contrast themes. 颜色主题允许你修改
描述 (Description) Framework7为您的应用程序提供不同的颜色主题。 颜色主题提供了不同类型的主题颜色,用于平滑地处理应用程序,如下表所示 - S.No 主题类型和描述 1 iOS主题颜色 您可以为应用程序使用10种不同的默认iOS颜色主题。 2 材料主题颜色 Framework7为应用程序提供了22种不同的默认材质颜色主题。 应用色彩主题 Framework7允许您通过将th
实现App外观主题切换功能,可以切换导航条、TabBar和字体的颜色,以及TabBar的按钮图片。 [Code4App.com]
我想以适当的方式使用colorPrimary和colorSecondary。 一个关于图像的好例子将对我有很大帮助。