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

Posted

技术标签:

【中文标题】如何在android中按名称访问可绘制资源【英文标题】:how to access the drawable resources by name in android 【发布时间】:2013-04-28 12:00:59 【问题描述】:

在我的应用程序中,我需要在不想保留引用 R 的地方获取一些位图可绘制对象。所以我创建了一个类DrawableManager 来管理drawables。

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/drawables 中):

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

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

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

还有其他选择吗?

【问题讨论】:

【参考方案1】:

请注意,您的方法几乎总是错误的做事方式(最好将上下文传递到使用可绘制对象的对象本身,而不是在某处保持静态Context)。

鉴于此,如果你想做动态可绘制加载,你可以使用getIdentifier:

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

【讨论】:

better to pass the context into the object itself that is using the drawable than keeping a static Context somewhere你好,你能告诉我更多吗? @hguser - 你想要 Drawable 的原因是在屏幕上显示它 - 每个视图/活动/片段都有一个与之关联的 Context - 将 Context 传递给你的getDrawable 方法。 我无法让它工作。即使可绘制对象可用并且我传递了正确的上下文,我的资源 id 也最终为 0。 @PratikMandrekar - 假设您正在尝试获取诸如 R.drawable.your_image 之类的资源,您会想要使用 resource.getIdentifier("your_image", "drawable", context.getPackageName()) - 如果没有特定代码,很难看出哪里出了问题。跨度> 注意你的资源名最后不能带扩展名(至少对于图片来说),否则你的resourceId会是0。不要把“picture.jpg”作为名字传,只传“picture” "。【参考方案2】:

你可以这样做。-

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"
    ....

【讨论】:

谢谢,我以前从来不知道我可以通过这种方式获取上下文。看起来它会让代码更干净。 以这种方式获取Context,而不是传递它,对可测试性不利。例如,要测试调用YourApplication.getContext() 的任何方法,测试必须首先实例化YouApplication 以使YourApplication.getContext() 不返回null。以静态的形式创建全局变量通常是一种不好的做法。【参考方案3】:

修改图片内容:

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

【讨论】:

【参考方案4】:

使用 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 中已弃用

注意:文件名,前"a.png"的名称将是"a"。。 p>

【讨论】:

【参考方案5】:

你可以这样实现

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

在 Imageview 中设置 resourceId

imageView.setImageResource(resourceId);

【讨论】:

你能解释一下这个答案是如何增加其他人没有的吗? (尤其是Raul!) 这个可以在类中调用吗!? 是的@Learn2Code【参考方案6】:

如果你需要 int 资源

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

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

【讨论】:

以上是关于如何在android中按名称访问可绘制资源的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中从 NDK 访问可绘制文件

Android:如何制作一个可绘制的选择器

如何在android中改变可绘制形状的颜色

如何在ggplot中按指定顺序绘制值向量?

如何在 VS2015 中按名称从解决方案资源管理器中隐藏文件?

如何在android中动态设置可绘制的图像?