Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 874
Michael Avatar asked Oct 30 '11 02:10

Michael


People also ask

What is attr in XML Android?

References in XML Thus, it is possible to combine color resources with the other simple resources in the XML file under one element: <resources>, but I don't recommend this practice. On the other hand ? attr is a reference to the theme attribute.

What is AttributeSet?

AttributeSet (Android Docs)A collection of attributes, as found associated with a tag in an XML document. Basically if you are trying to create a custom view, and you want to pass in values like dimensions, colors etc, you can do so with AttributeSet .


2 Answers

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).

like image 161
XåpplI'-I0llwlg'I - Avatar answered Sep 16 '22 11:09

XåpplI'-I0llwlg'I -


The other answer works well with array of strings. However, arr.getTextArray(...) on array of references, e.g.

<array name="tmp">   <item>@drawable/a</item>   <item>@drawable/b</item> </array> 

will give you res/drawable/a.png as the CharSequence instead of the resource id.

The proper way to parse an array of references is this:

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);  int arrayResourceId = typedArray.getResourceId(R.styleable.CustomView_CustomAttr, 0); if (arrayResourceId != 0) {     final TypedArray resourceArray = getResources().obtainTypedArray(arrayResourceId);     for (int i = 0; i < resourceArray.length(); i++) {         final int resourceId = resourceArray.getResourceId(i, 0);          // do stuff with resourceId, such as getResources().getDrawable(resourceId)     }     resourceArray.recycle(); } typedArray.recycle(); 
like image 27
Jin Avatar answered Sep 18 '22 11:09

Jin