-2

Background

I'm trying to set a custom margin value on the listView items based on the selected theme.

The app has multiple themes, and the user can choose which theme to use , which I set by calling "setTheme()" .

The problem

whatever I try, I get this error:

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

note that this occurs only for the margin attribute, and so far no other attribute has caused this.

What I've tried

first, here's the xml snippets I've used

attrs.xml

<attr name="listview_item__horizontal_spacing" format="dimension" />

styles.xml

<style name="AppTheme_HoloDark" parent="@style/Theme.Sherlock">
  <item name="listview_item__horizontal_spacing">4dp</item>
  ....

the layout of the listView item:

<RelativeLayout ...
    android:layout_marginLeft="?attr/listview_item__horizontal_spacing" >

I've also tried using "reference" for the attribute type, and reference to a "dimen" resource, but it also cause the same exception.

Another thing I've tried is getting it dynamically:

public static int getResIdFromAttribute(final Activity activity,final int attr)
    {
    final TypedValue typedvalueattr=new TypedValue();
    activity.getTheme().resolveAttribute(attr,typedvalueattr,true);
    return typedvalueattr.resourceId;
    }

...
final int spacingResId=getResIdFromAttribute(activity,R.attr.listview_item__horizontal_spacing);

but for some reason I get 0 as the result of this call. Only when using this method it worked.

The question

What is going on? How can I avoid this?

Is there really no way to overcome this but using code (when inflating the xml) ?

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270

1 Answers1

2

You don't need to use attr XML, and this is your issue.

Place your the value you want in a file named dimens.xml in your res folder (same location as strings.xml).

This file will look something like this:

<resources>
    <dimen name="value1">15dp</dimen>
    <dimen name="value2">20dp</dimen>
</resources>

Then in your layout XML, you can reference the dimen directly (just as you would reference a string), something like this:

<RelativeLayout ...
    android:layout_marginLeft="@dimen/value1" >

or when defining a style, in your XML it would look like:

 <style name="MyStyle1">
        <item name="android:layout_marginLeft">@dimen/value1</item>
    </style>

and then for your other style:

<style name="MyStyle2">
            <item name="android:layout_marginLeft">@dimen/value2</item>
        </style>
Booger
  • 18,579
  • 7
  • 55
  • 72
  • I want to set the dimension based on the current theme (which the user can choose, and then I use "setTheme()" before the activity is really created. What you've offered here is completely static. – android developer Apr 20 '14 at 15:13
  • You will need to just create the logic to make these changes. You would put a different dimen value each of your styles (ie. a different value entirely for each style, that has it's own unique value in the dimen folder). – Booger Apr 20 '14 at 19:39
  • Added solution to answer. – Booger Apr 20 '14 at 19:41
  • What you've written is still very static. I need to support : setTheme(R.style.MyTheme1) and setTheme(R.style.MyTheme2) , each will have the dimension of the margin to a different value. – android developer Apr 20 '14 at 20:35
  • When you change between MyTheme1 and MyTheme2, the dimen will change from Value1 to Value2 - this is exactly what my answer shows, and is the correct way to do this. – Booger Apr 20 '14 at 21:25
  • You didn't write a theme that changes the margin. you've written about themes that change the text size. the margin attribute in what you've written will always point to "@dimen/value1" , no matter which theme is used. – android developer Apr 20 '14 at 21:51
  • I changed that (thought you might figure out they concept). This example is now accurate. – Booger Apr 21 '14 at 03:39
  • What you've written will change the margin for all views, and I wish to do it for a specific ones that use the attribute I've set. What I want is : set the theme for the entire activity, and each attribute that is used on a view will match according to what the theme specifies. The current attribute I've asked about is used for specific views, on their margins. – android developer Apr 21 '14 at 08:39