如何使用TypedArray获取Drawable(具有可绘制别名)

时间:2014-09-29 18:21:54

标签: android android-resources android-drawable

所以,根据Android文档,Resources.getDrawable()在Jelly Bean之前有一个OS版本的已知错误,其中别名drawables无法用正确的密度解析(因此drawable-hdpi中的100px图像被升级为在HDPI设备上150px):

  

注意:在JELLY_BEAN之前,当此处传递的资源ID是另一个Drawable资源的别名时,此函数将无法正确检索最终配置密度。这意味着如果别名资源的密度配置与实际资源不同,则返回的Drawable的密度将不正确,从而导致错误的缩放。要解决此问题,您可以通过TypedArray.getDrawable检索Drawable。将Context.obtainStyledAttributes与包含感兴趣的资源ID的数组一起使用,以创建TypedArray。

但是,我无法使用指定的说明真正解析Drawable。我写的一种实用方法:

@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;
}
当我传递可绘制别名的资源ID时,

始终返回null,我在res/values/drawables.xml中定义为:

<item name="my_drawable" type="drawable">@drawable/my_drawable_variation</item>

我在这里缺少某些东西或其他一些解决方法吗?

编辑:我在下面添加了一个解决方案。

1 个答案:

答案 0 :(得分:1)

好吧,我发现以下解决方案似乎可以解决问题:

/**
 * 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);
}