Using an array reference as an XML attribute for custom android view

Michael picture Michael · Oct 30, 2011 · Viewed 17.1k times · Source

This problem has been solved, see comments for details.

I am extending an existing Android View and loading some custom attributes, as described in Declaring a custom android UI element using XML and Defining custom attrs.

Attributes with boolean and integer formats work fine, but when I try to specify a reference to an array resource, the application crashes at launch. I have defined an integer array inside an xml resource file and I'm trying to use it as an attribute for the custom view.

I can use the array resource to set the "entries" attribute of the android Spinner class with no errors, so it seems to be a problem in my implementation. The logcat messages don't seem to supply any specific information about the crash, but I'm still looking so I will update if I find something.

The attributes are declared by (in attrs.xml):

<declare-styleable name="CustomView">
    <attr name="values" format="reference"/>
    <attr name="isActive" format="boolean"/>
</declare-styleable>

The array is defined as (in arrays.xml):

<integer-array name="nums">
    <item>1</item>
    <item>2</item>
    <item>3</item>
</integer-array>

And I am referencing the array by:

<com.test.CustomView cv:values="@array/nums" />

And this causes the application to crash immediately. In addition, if I reference a color resource instead of an array then the application does not crash. Does anybody know how to deal with this problem?

Answer

X&#229;pplI&#39;-I0llwlg&#39;I  - picture XåpplI'-I0llwlg'I - · Jan 3, 2013

Just going to piggyback off your question here, since your post shows up first if you google something like "array reference XML attribute custom view", so someone might find this helpful.

If you want your custom view to reference an array of strings, you can use Android's existing android:entries XML attribute, instead of creating a totally new custom attribute.

Just do the following in res/values/attrs.xml:

<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:entries" />
    </declare-styleable>
</resources>

Then do this in your custom View's constructor:

public MyCustomView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
    try
    {
        CharSequence[] entries = a.getTextArray(R.styleable.MyCustomView_android_entries);
        if (entries != null)
        {
           //do something with the array if you want
        }
    }
    finally
    {
        a.recycle();
    }
}

And then you should be able to reference a string array via the android:entries attribute when you add your custom View to an XML layout file. Example:

<com.example.myapp.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:entries="@array/my_array_of_strings" />

This is exactly how it is done in the ListView class (look in the source, you'll see).