Issue
So, according to the Android documentation, Resources.getDrawable()
has a known bug for OS versions before Jelly Bean, where aliased drawables would not be resolved with the correct density (so a 100px image in drawable-hdpi gets upscaled to 150px on an HDPI device):
Note: Prior to JELLY_BEAN, this function would not correctly retrieve the final configuration density when the resource ID passed here is an alias to another Drawable resource. This means that if the density configuration of the alias resource is different than the actual resource, the density of the returned Drawable would be incorrect, resulting in bad scaling. To work around this, you can instead retrieve the Drawable through TypedArray.getDrawable. Use Context.obtainStyledAttributes with an array containing the resource ID of interest to create the TypedArray.
However, I've not been able to actually resolve a Drawable
using the instructions specified. A utility method that I've written:
@NonNull
public static Drawable resolveDrawableAlias(@NonNull Context ctx, @DrawableRes int drawableResource) {
final TypedArray a = ctx.obtainStyledAttributes(new int[] { drawableResource });
final Drawable result = a.getDrawable(0);
a.recycle();
return result;
}
always returns null when I'm passing in a resource ID for a drawable alias, which I've defined in res/values/drawables.xml
as:
<item name="my_drawable" type="drawable">@drawable/my_drawable_variation</item>
Is there something I'm missing here, or some other workaround?
EDIT: I've added a solution below.
Solution
Alright, I've found the following solution which seems to do the trick:
/**
* Method used as a workaround for a known bug in
* {@link android.content.res.Resources#getDrawable(int)}
* where the density is not properly resolved for Drawable aliases
* on OS versions before Jelly Bean.
*
* @param ctx a context for resources
* @param drawableResource the resource ID of the drawable to retrieve
*
* @return the Drawable referenced by drawableResource
*/
@NonNull
public static Drawable resolveDrawableAlias(@NonNull Context ctx, @DrawableRes int drawableResource) {
final TypedValue value = new TypedValue();
// Read the resource into a TypedValue instance, passing true
// to resolve all intermediate references
ctx.getResources().getValue(drawableResource, value, true);
return ctx.getResources().getDrawable(value.resourceId);
}
Answered By - Kevin Coppock
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.