You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android根据Drawable图片名称字符串设置ImageView的问题

Android 根据图片名称设置ImageView到RecyclerView的解决方案

先解决getResources()废弃的问题

API 33之后getResources()被标记为废弃,替代方案是使用ContextCompat.getResources(Context),在Activity里可以这么写:

int resId = ContextCompat.getResources(this).getIdentifier(imageName, "drawable", getPackageName());

当然旧的getResources()目前仍能正常运行,只是官方不再推荐使用。

你的代码没效果的核心原因

getIdentifier()返回0就代表没找到对应资源,大概率是这几个问题:

  • 文件名大小写不匹配:Android资源文件名仅支持小写字母、数字、下划线、连字符,数据库返回的名称如果有大写,必须转成小写后再查找:
    int resId = ContextCompat.getResources(this).getIdentifier(imageName.toLowerCase(), "drawable", getPackageName());
    
  • 资源目录放错:确保图片在res/drawable目录下,而非mipmap(mipmap是专门存放应用图标的目录)。
  • 混淆导致资源被移除:如果开启了ProGuard,它会删除未被硬编码引用的资源,需要在proguard-rules.pro中添加规则保留drawable的ID类:
    -keep class **.R$drawable { *; }
    
  • 未判断resId是否为0:没找到资源时resId会是0,此时setImageResource(0)不会显示任何内容,必须加判断兜底:
    if (resId != 0) {
        holder.imageSection.setImageResource(resId);
    } else {
        // 设置默认图避免空白
        holder.imageSection.setImageResource(R.drawable.default_image);
    }
    

更高效的替代方案(推荐)

getIdentifier()基于反射实现,性能差且易出错,不如提前把图片名称和对应resId做成映射表:

  1. 在Application或Activity的onCreate中初始化映射关系:
HashMap<String, Integer> drawableNameMap = new HashMap<>();
drawableNameMap.put("cat", R.drawable.cat);
drawableNameMap.put("dog", R.drawable.dog);
// 将所有需要用到的图片名称与ID一一对应添加
  1. 从数据库拿到名称后,直接从Map中取ID:
Integer resId = drawableNameMap.get(imageName.toLowerCase());
if (resId != null) {
    // 将resId传入RecyclerView适配器
}
  1. 适配器中直接设置图片:
holder.imageSection.setImageResource(resId);

为什么Android不能像iOS那样直接用名称?

Android的资源会被编译成唯一整数ID,系统还会根据设备分辨率、语言等自动匹配对应目录下的资源,并非直接按文件名读取,因此必须通过ID定位资源。而iOS的Bundle是直接按文件名查找资源,两者的资源管理机制存在本质差异。

内容的提问来源于stack exchange,提问作者Nicholas Farmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:03:18