How to reference style attributes from a drawing?

I want to have two themes for my application. For this, I defined some attributes, for example:

<attr format="color" name="item_background" /> 

Then I created both themes, for example:

  <style name="ThemeA"> <item name="item_background">#123456</item> </style> <style name="ThemeB"> <item name="item_background">#ABCDEF</item> </style> 

This method works great, which allows me to easily create and modify multiple themes. The problem is that it seems that it can only be used in views, and not in Drawables .

For example, a link to a value from a view inside a layout works:

  <TextView android:background="?item_background" /> 

But doing the same in Drawable does not:

  <shape android:shape="rectangle"> <solid android:color="?item_background" /> </shape> 

I get this error when starting the application:

  java.lang.UnsupportedOperationException: Can't convert to color: type=0x2 

If I use hard code instead of ?item_background , it works, but this does not allow me to use my themes. I also tried ?attr:item_background , but the same thing happens.

How can i do this? And why does it work in Views, but not in Drawables? I cannot find this restriction anywhere in the documentation ...

+72
android android-drawable android-theme
Nov 07 2018-11-11T00:
source share
4 answers

In my experience, it's not possible to reference an attribute in xml drawable.
To make your theme you need:

  • Create one xml for each theme.
  • Include the desired color in the rectified directly with the @color or #RGB tag.

Create an attribute for your drawable in attrs.xml.

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

Add your drawable to your theme.xml.

 <style name="MyTheme" parent="@android:style/Theme.NoTitleBar"> <item name="my_drawable">@drawable/my_drawable</item> </style> 

Link to your drawings in your layout using your attribute.

 <TextView android:background="?my_drawable" /> 
+131
Nov 20 '12 at 10:55
source share

Starting with lollipop (API 21) this feature is supported, see https://code.google.com/p/android/issues/detail?id=26251

However, if you target devices without candy, don’t use it, as it will crash, use the workaround in the accepted answer.

+14
May 20 '15 at 13:47
source share

It is not possible to refer to style attributes from drawables on pre-Lollipop devices, but this is possible for color state lists. You can use the AppCompatResources.getColorStateList method (context context, int resId) from the Android support library. The downside is that you have to program these color state lists.

Here is a very simple example.

color / 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> 

A widget that needs a list of color states:

 <RadioButton android:id="@+id/radio_button" android:text="My Radio" /> 

And the most important thing:

 ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_color_state); RadioButton r = (RadioButton) findViewById(R.id.radio_button); r.setTextColor(csl); 

Well, not the most elegant or the shortest way, but this is what the Android Support Library does to make it work with older versions of (pre-Lollipop) Android.

Unfortunately, a similar method for drawables does not work with style attributes.

+3
Dec 10 '16 at 23:59
source share

As @marmor said, this is now supported by API 21. But for those who need support for legacy versions of Android, you can use this feature. Using the v7 support library, you can still use it in applications with a minimum SDK of up to 7.

An error has been implemented in this function in the AppCompatImageView in the Android v7 support library. Just replace your ImageView words with AppCompatImageView .

0
May 11 '16 at 3:51
source share



All Articles