如何在drawable中引用颜色属性?

46

我想做一件简单的事情:定义一个drawable,它的背景颜色与系统状态-按下状态的背景颜色完全相同。 我在res / drawables / my_drawable.xml中这样做:

<?xml version="1.0" encoding="utf-8"?>
  <selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true">
      <color android:color="?android:attr/colorPressedHighlight"/>
    </item>
    <item android:state_selected="false">
      <color android:color="@color/section_list_background"/>
    </item>    
  </selector>

我总是得到:

java.lang.UnsupportedOperationException: Cant convert to color: type=0x2

有什么线索吗?

致敬

4个回答

72
您可能需要执行以下步骤来解决您的问题:

1)在您的颜色文件中为每个主题定义2种颜色:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="my_color_dark">#ff33B5E5</color>
    <color name="my_color_light">#ff355689</color>
</resources>

2)创建文件 res/values/attrs.xml,其内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="my_color" format="reference" />
</resources>

3)假设你在styles.xml中有两个主题(Theme.darkTheme.light),请定义:

<style name="Theme.dark" parent="@style/Theme.Sherlock">
    <item name="my_color">@color/my_color_dark</item>
</style>

<style name="Theme.light" parent="@style/Theme.Sherlock.Light">
    <item name="my_color">@color/my_color_light</item>
</style>

4) 将颜色用于可绘制对象:

<color android:color="?attr/my_color"/>

希望这可以解决你的问题。

14
由于某种原因,我使用这种方法时出现错误:android.view.InflateException: Binary XML file line #2: Error inflating class <unknown> - Muxa
2
如果我尝试这种方法,我会得到相同的错误。它适用于布局xml中的android:color,但不适用于drawable xml。一个繁琐的解决方法: final TypedValue typedValue = new TypedValue(); getTheme().resolveAttribute(R.attr.tx_frq, typedValue, true); COLOR = typedValue.data; Drawable d = getResources().getDrawable(R.drawable.mydrawable); d.setColorFilter(COLOR, PorterDuff.Mode.MULTIPLY); - Larphoid
2
此解决方案仅适用于API 11及以上版本。对于API 10及以下版本,您无法在Drawable xml文件中引用属性。 - BladeCoder
15
更正 BladeCoder 的评论,这个解决方案适用于 API 21+。参考资料:https://code.google.com/p/android/issues/detail?id=26251。 - Eric Chen

9

在XML可绘制资源中不能使用?attr,因为这些可绘制资源是由AAPT在编译时创建的。属性资源用于运行时的动态连接。


7

您正试图将属性转换为颜色。属性通常附加到视图上,可以使用主题进行样式化。

您需要在xml中引用一个颜色资源。您可以通过创建自己的资源来实现:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPressedHighlight">#FF8800</color>
</resources>

然后像这样引用它:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true">
        <color android:color="@color/colorPressedHighlight"/>
    </item>
    <item android:state_selected="false">
        <color android:color="@color/section_list_background"/>
    </item>    
</selector>

或者您可以引用Android资源中可用的颜色:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true">
        <color android:color="@android:color/holo_orange_light"/>
    </item>
    <item android:state_selected="false">
        <color android:color="@android:color/holo_blue_dark"/>
    </item>
</selector>

好的,我明白了你的意思。也许我使用了错误的想法。让我告诉你我想要实现什么。我有一些自定义视图,我想将其选中状态的背景颜色设置为与实际主题按下状态颜色完全相同。我认为我不能使用@android:color/...来实现这一点。 - Michal
你是否正在使用官方的Android主题?那么你可以链接到颜色,或者只需从$ANDROID_SDK$/platforms/android-14/data/res中获取可绘制对象。 - XGouchet
是的,我同意,但是当我想在我的应用程序中允许更改主题时,我将不得不自己处理自定义可绘制对象的颜色更改。我认为我可以通过将其背景颜色与属性值粘合来自动完成这个过程。 - Michal
你所说的主题是自定义主题吗?如果是,你可以在自定义视图上更改自定义属性来改变你的主题。 - XGouchet
我有一个例子在脑海中。假设我允许用户更改主题(可以选择Holo和Holo.Light之一)。当他更改主题时,文本和背景的颜色将会改变。我想要实现的是,我希望将我的自定义视图背景与某些属性捆绑在一起,这样当用户更改主题时,颜色也会改变。 - Michal
那么您最好的解决方案是创建两个自定义主题,将Holo和Holo.Light作为其父主题,并使这些主题也更改您的自定义视图。 - XGouchet

0
尝试将颜色放入android:drawable中,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="?android:attr/colorPressedHighlight"/> <!-- pressed -->
    <item android:state_focused="true" android:drawable="@color/blue"/> <!-- focused -->
    <item android:drawable="@color/section_list_background"/> <!-- default -->
</selector>

或者

<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_focused="true" android:color="?android:attr/colorPressedHighlight"/>
   <item android:state_enabled="false" android:color="@color/section_list_background" />
   <item android:color="@color/testcolor5"/>
 </selector>

http://developer.android.com/guide/topics/resources/drawable-resource.html - Dheeresh Singh
你检查过了吗?我尝试使用时遇到了错误:<item android:state_pressed="true" android:drawable="?android:attr/colorPressedHighlight"/> - Michal
我只想说,如果你想使用“item android:state_selected”,请使用你的状态,但使用android:drawable作为属性来设置颜色...... - Dheeresh Singh

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