如何引用可绘制的样式属性?
我想为我的应用程序有2个可选的主题。 为了做到这一点,我定义了一些属性,如下所示:
<attr format="color" name="item_background" />
然后,我创build了这样的主题:
<style name="ThemeA"> <item name="item_background">#123456</item> </style> <style name="ThemeB"> <item name="item_background">#ABCDEF</item> </style>
这种方法效果很好,使我能够轻松地创build和修改几个主题。 问题是, 它似乎只能在视图中使用,而不能在Drawable中使用 。
例如,从布局中的View中引用值的工作原理如下:
<TextView android:background="?item_background" />
但是在Drawable中做同样的事情不会:
<shape android:shape="rectangle"> <solid android:color="?item_background" /> </shape>
运行应用程序时出现此错误:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
如果不是?item_background
我使用硬编码的颜色,它的工作原理,但是这不允许我使用我的主题。 我也尝试过?attr:item_background
,但是也是一样的。
我怎么能这样做? 为什么它在视图中工作,而不是在Drawable中? 我无法在文档中的任何位置find此限制…
根据我的经验,不可能在xml drawable中引用一个属性。
为了使你的主题,你需要:
- 为每个主题创build一个xml drawable。
-
用
@color
标记或#RGB格式直接绘制所需的颜色。
在attrs.xml中为您的drawable 创build一个属性。
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- Attributes must be lowercase as we want to use them for drawables --> <attr name="my_drawable" format="reference" /> </resources>
将你的drawable添加到你的theme.xml中 。
<style name="MyTheme" parent="@android:style/Theme.NoTitleBar"> <item name="my_drawable">@drawable/my_drawable</item> </style>
使用属性在布局中引用绘图。
<TextView android:background="?my_drawable" />
从lollipop
(API 21)开始支持此function,请参阅https://code.google.com/p/android/issues/detail?id=26251
但是,如果您的目标设备没有棒棒糖,请不要使用它,因为它会崩溃,请使用接受的答案中的解决方法。
尽pipe无法在前棒棒糖设备上引用可绘制的样式属性,但颜色状态列表是可能的。 您可以使用Android支持库的AppCompatResources.getColorStateList(Context context,int resId)方法。 缺点是你将不得不以编程方式设置这些颜色状态列表。
这是一个非常基本的例子。
彩色/ my_color_state.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:color="?colorControlActivated" /> <item android:color="?colorControlNormal" /> </selector>
需要颜色状态列表的小部件:
<RadioButton android:id="@+id/radio_button" android:text="My Radio" />
而最重要的是:
ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_color_state); RadioButton r = (RadioButton) findViewById(R.id.radio_button); r.setTextColor(csl);
那么,不是最优雅或最短的方式,但这是Android支持库,以使其在Android的旧版本(前棒棒糖)上工作。
不幸的是, 类似的绘图方法不适用于样式属性。
正如@marmor所言,API 21现在支持这种技术。但对于那些需要支持旧版Android的用户,您可以使用此function。 使用v7支持库,您仍然可以将使用最低SDK级别的应用程序一直使用到7。
v7 Android支持库中的AppCompatImageView
具有此function的无bug实现。 只需用AppCompatImageView
replaceImageView
的用法。