如何在Android中按名称访问可绘制资源


72

在我的应用程序中,我需要将一些位图可绘制对象放置在不想保留reference的位置R。因此,我创建了一个类DrawableManager来管理可绘制对象。

public class DrawableManager {
    private static Context context = null;

    public static void init(Context c) {
        context = c;
    }

    public static Drawable getDrawable(String name) {
        return R.drawable.?
    }
}

然后我想通过这样的名称获取drawable(将car.png放在res / drawables内):

Drawable d= DrawableManager.getDrawable("car.png");

但是,如您所见,我无法通过名称访问资源:

public static Drawable getDrawable(String name) {
    return R.drawable.?
}

还有其他选择吗?

Answers:


164

请注意,您的方法几乎总是错误的处理方式(最好是将上下文传递给使用drawable的对象本身,而不是在Context某个地方保持静态)。

鉴于此,如果您想进行动态可绘制加载,则可以使用getIdentifier

Resources resources = context.getResources();
final int resourceId = resources.getIdentifier(name, "drawable", 
   context.getPackageName());
return resources.getDrawable(resourceId);

1
better to pass the context into the object itself that is using the drawable than keeping a static Context somewhere嗨,你能告诉我更多吗?
hguser

1
@hguser-您想要的原因Drawable是将其显示在屏幕上-每个视图/活动/片段都有Context关联-将其传递Context到您的getDrawable方法中。
ianhanniballake

1
我莫名其妙地不能使它工作。即使可绘制对象可用并且我正在传递正确的上下文,我的资源ID最终还是为0。
Pratik Mandrekar

2
@PratikMandrekar-假设您尝试获取诸如的资源R.drawable.your_image,而您想使用resource.getIdentifier("your_image", "drawable", context.getPackageName())-没有特定的代码,很难发现问题所在。
ianhanniballake

请注意,您的资源名称的末尾应没有扩展名(至少对于图片而言),否则您的resourceId将为0。请勿将“ picture.jpg”作为名称传递,仅传递“ picture”。
Michael Abyzov

23

你可以做这样的事情。

public static Drawable getDrawable(String name) {
    Context context = YourApplication.getContext();
    int resourceId = context.getResources().getIdentifier(name, "drawable", YourApplication.getContext().getPackageName());
    return context.getResources().getDrawable(resourceId);
}

为了从任何地方访问上下文,您可以扩展Application类。

public class YourApplication extends Application {

    private static YourApplication instance;

    public YourApplication() {
        instance = this;
    }

    public static Context getContext() {
        return instance;
    }
}

并将其映射到您的Manifest application标签中

<application
    android:name=".YourApplication"
    ....

3
谢谢,我从来不知道我可以这样获得上下文。看来它将使代码更整洁。
hguser

Context以这种方式获取而不是传递它对于可测试性不利。例如,要测试任何调用的方法,YourApplication.getContext()测试必须首先实例化YouApplication,以便YourApplication.getContext()不返回null。以静态形式创建全局变量通常是一种不好的做法。
spaaarky21 '17

8

修改图片内容:

    ImageView image = (ImageView)view.findViewById(R.id.imagenElement);
    int resourceImage = activity.getResources().getIdentifier(element.getImageName(), "drawable", activity.getPackageName());
    image.setImageResource(resourceImage);

1

使用Kotlin

fun Context.getResource(name:String): Drawable? {
    val resID = this.resources.getIdentifier(name , "drawable", this.packageName)
    return ActivityCompat.getDrawable(this,resID)
}

我将其编写为扩展功能,因此可以在代码中的任何位置使用它。

注:context.getResources().getDrawable(resourceId);弃用Java编写的。

注意:文件名,是不带扩展名的文件,例如ex “ a.png”的名称将是“ a”


0

如果您需要int资源

 Resources resources = context.getResources();
 int resourceId = resources.getIdentifier("eskb048", "drawable",context.getPackageName());
 // return like: R.drawable.eskb048.png

如果您需要Drawable,请检查第一个答案是否正确


0

你可以这样实现

int resourceId = getResources().getIdentifier("your_drawable_name", "drawable", getPackageName());

在Imageview中设置resourceId

imageView.setImageResource(resourceId);

您能解释一下这个答案如何添加其他人没有的东西吗?(特别是Raul给出的!)
Adrian Mole
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.