如何在 android 中通过名称访问可绘制的资源

在我的应用程序中,我需要得到一些位图绘制的地方,我不想保持参考 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.?
}
}

然后我想通过名称来获取可绘制的内容,如下所示(car.png 放在 res/draables 中) :

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

然而,正如您所看到的,我无法通过名称访问资源:

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

还有别的选择吗?

76484 次浏览

Note that your approach is almost always the wrong way to do things (better to pass the context into the object itself that is using the drawable than keeping a static Context somewhere).

Given that, if you want to do dynamic drawable loading, you can use getIdentifier:

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

You could do something like this.-

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

In order to access the context from anywhere, you may extend Application class.-

public class YourApplication extends Application {


private static YourApplication instance;


public YourApplication() {
instance = this;
}


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

And map it in your Manifest application tag

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

Modify image content:

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

Using Kotlin

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


I wrote it as Extension function so It can be used at any place in code.

Note: context.getResources().getDrawable(resourceId); is deprecated in Java.

Note: name of file,is name without extensions for ex "a.png" name will be "a".

if You need int resouce

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

if your need Drawable check the first answer is correct for all

You can achieve like this

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

Set resourceId In Imageview

imageView.setImageResource(resourceId);

The best solution would be to create a map of your icons in your code

val iconMap: HashMap<String, Int>

String is your key (to that drawable resource) that you can keep in your database, or even the key from backend API response

Int is the resource drawable

iconMap.put("cat", R.drawable.ic_cat)
iconMap.getOrDefault("dog", R.drawable.empty)

This way you make resource usage more visible to other devs