46

I would like to do a simple thing: Define a drawable which has exacly same background colour as system state-pressed background colour. I do it like this in 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>

I always get:

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

Any clues?

Regards

Michal
  • 2,074
  • 2
  • 22
  • 29

4 Answers4

72

You might need to do the following to fix your problem:

1) Define 2 colors for each theme in your colors file:

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

2) Create file res/values/attrs.xml with contents:

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

3) Assuming you have 2 themes in your styles.xml (Theme.dark and Theme.light) define:

<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) Use the color in a drawable:

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

Hope this should fix your problem.

petrsyn
  • 5,054
  • 3
  • 45
  • 48
  • 14
    For some reason i get an error with this approach: `android.view.InflateException: Binary XML file line #2: Error inflating class ` – Muxa Jun 15 '14 at 23:12
  • 2
    I'm getting the same error if I try this approach. It works for android:color in layout xml's but not drawable xml's. A tedious workaround: 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 Aug 08 '14 at 23:35
  • 2
    This solution works on API 11+ only. For API 10 and lower, you can't reference an attribute inside a Drawable xml file. – BladeCoder Jan 11 '15 at 01:01
  • 15
    Correction to @BladeCoder comment, this solution works on API 21+. Reference: https://code.google.com/p/android/issues/detail?id=26251. – Eric Chen Mar 15 '15 at 14:23
9

you can't use ?attr in xml drawable resources because drawable resources created by aapt in compile time. Attr resources used for dynamic connection in runtime

Alexander Blinov
  • 393
  • 3
  • 13
6

You're trying to convert an attribute into a color. Attributes are properties usually attached to a view, which can then be styled using a theme.

You need to reference a color resource in your xml. You can do so by creating your own resource :

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

Then reference it like this :

<?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>

Or you can reference a color available in the Android 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="@android:color/holo_orange_light"/>
    </item>
    <item android:state_selected="false">
        <color android:color="@android:color/holo_blue_dark"/>
    </item>
</selector>
XGouchet
  • 10,002
  • 10
  • 48
  • 83
  • Ok I got your point. Maybe I am using wrong idea. Let me tell you what I would like to achieve. I have some custom view and I would like to set it selected-state background colour exacly the same as actual theme pressed-state colour. Think I will not achieve this using `@android:color/...`. – Michal Jun 12 '12 at 10:48
  • Are you using official Android Themes ? then you can link to the color, or just get the drawables from the sdk in $ANDROID_SDK$/platforms/android-14/data/res. – XGouchet Jun 12 '12 at 11:44
  • Yes I agree, but when I would like to allow changing theme in my app I will have to handle colour change of custom drawable on my own. I thought I could do this somehow automatically - sticking its background colour with attr value. – Michal Jun 12 '12 at 11:53
  • Are the Themes you talk about custom themes ? if so you can make your theme change a custom attribute on your custom view – XGouchet Jun 12 '12 at 11:58
  • I have such example in mind. Let`s say that I allow user to change Theme (can pick one of Holo and Holo.Light). When he changes Theme the colours of text, background will change. What I wanted to achieve is that I would like to stick my custom view background with some attribute, so the colour will be changed when user change Theme. – Michal Jun 12 '12 at 13:04
  • Then your best solution would be to create Two custom theme with Holo and Holo.Light as parent, and make those themes also change your custom view. – XGouchet Jun 12 '12 at 13:09
0

try this way put color in android:drawable as below

<?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>

or

<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>
Dheeresh Singh
  • 15,643
  • 3
  • 38
  • 36