Issue
For our current app, almost all of our resources are themed. For the most part this works, but I can't figure out how to parse themed resources out of a resource array.
The code we have for parsing color arrays looks something like this:
TypedArray ca = getResources().obtainTypedArray(id);
int[] colors = new int[ca.length()];
for (int i = 0; i < colors.length; i++)
{
colors[i] = ca.getColor(i, 0);
}
ca.recycle();
That works fine as long as the array looks something like this:
<array name="color_array_foo">
<item>#123456</item>
<item>#789ABC</item>
</array>
But if the array looks like this:
<array name="color_array_foo">
<item>?attr/color_nothing</item>
<item>?attr/color_1</item>
</array>
with the necessary stuff elsewhere in resources like:
<attr name="color_1" format="color"/>
...
<style name="Base" parent="@android:style/Theme.NoTitleBar">
<item name="color_1">#123456</item>
...
</style>
then it throws this exception:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
at android.content.res.TypedArray.getColor(TypedArray.java:327)
I've looked around at the various methods of TypedArray, like peekValue() and getResourceId(), but I can't figure out anything that will let me dereference the themed attribute to the actual color value. How do I do that?
Edit: This smells like it's closer, but still isn't right:
TypedArray ca = getResources().obtainTypedArray(id);
int [] c = new int[ca.length()];
for (int i=0; i<c.length; i++)
{
if (ca.peekValue(i).type == TypedValue.TYPE_REFERENCE ||
ca.peekValue(i).type == TypedValue.TYPE_ATTRIBUTE)
{
// FIXME: Probably need to split the above if, and for
// TYPE_ATTRIBUTE, do some additional dereferencing?
c[i] = ca.getResources().getColor(ca.peekValue(i).data);
}
else
{
c[i] = ca.getColor(i, 0);
}
}
ca.recycle();
Solution
Use method public boolean resolveAttribute (int resid, TypedValue outValue, boolean resolveRefs)
TypedArray ca = getResources().obtainTypedArray(id);
int[] c = new int[ca.length()];
for (int i = 0; i < c.length; i++) {
if (ca.peekValue(i).type == TypedValue.TYPE_ATTRIBUTE) {
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(ca.peekValue(i).data, typedValue, true);
c[i] = typedValue.data;
} else {
c[i] = ca.getColor(i, 0);
}
}
ca.recycle();
it works for
<resources>
<attr name="color_2" format="color"/>
<color name="color_2">#002</color>
<color name="color_3">#003</color>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="color_2">@color/color_2</item>
</style>
<array name="color_array_foo">
<item>#001</item>
<item>?attr/color_2</item>
<item>@color/color_3</item>
</array>
</resources>
Answered By - gio
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.