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?
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.
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 .
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).
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With