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

Android中如何访问带区域设置限定符的Drawable资源?

问题根源

你误解了Android资源限定符的核心逻辑:资源限定符是让系统根据当前Locale自动加载同名资源,而非用来区分不同名称的资源。你把不同国旗用不同文件名(french_flag、german_flag)放在区域限定文件夹的做法,完全违背了Android资源系统的设计规则,这就是你遇到编译错误和资源找不到问题的根本原因。

正确实现方案

1. 统一资源文件名

按照Android资源规范调整文件结构:

  • 主drawable文件夹放入美国国旗,命名为flag.png(作为默认资源)
  • 创建drawable-fr文件夹,放入法国国旗,文件名保持flag.png
  • 创建drawable-de文件夹,放入德国国旗,文件名保持flag.png

2. 常规加载资源

直接通过统一的资源ID加载,系统会自动根据当前设备Locale匹配对应区域的国旗:

// Kotlin 示例
imageView.setImageResource(R.drawable.flag)
// Java 示例
imageView.setImageResource(R.drawable.flag);

3. 手动切换Locale后的资源适配

如果通过Locale.setDefault()修改了应用Locale,需要更新Resources对象后再加载资源,或者重建Activity让系统自动适配:

方式一:更新Resources对象

// Kotlin 示例
val targetLocale = Locale("fr")
Locale.setDefault(targetLocale)

// 创建适配新Locale的配置
val newConfig = resources.configuration.apply {
    setLocale(targetLocale)
}
// 获取新的Resources对象
val updatedResources = createConfigurationContext(newConfig).resources
// 加载资源
imageView.setImageResource(updatedResources.getIdentifier("flag", "drawable", packageName))

方式二:重建Activity(更简便)

修改Locale后直接重建当前Activity,系统会自动使用新Locale匹配资源:

// Kotlin 示例
Locale.setDefault(Locale("de"))
recreate()
关于getIdentifier返回0的原因

你之前遇到Resources$NotFoundException是因为:

  • 修改Locale后,原有Resources对象仍适配旧Locale,此时去查找仅存在于特定区域文件夹的异名资源(比如french_flag),系统无法找到对应资源,返回0
  • 正确用法是配合同名资源使用,让资源系统自动完成匹配,而非手动指定异名资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:45:03