本节摘要:res 目录是界面的后勤仓库——目录即分类、文件名即 id、限定词即环境开关。本节逐格看清各子目录的职责、@引用语法、资源命名禁令与 mipmap 的密度桶,为后两节的样式体系打好地基。
前面章节已经零散用过 @string/、@drawable/、@dimen/,现在把整个仓库摊开看。res 的组织法则只有三句:目录决定类型,文件名变成 id,限定词切换环境。先看目录编制:
res/ drawable/ 图形与矢量图(ic_face_smile.xml) mipmap/ 应用图标专用(按密度分桶) layout/ 布局文件(activity_main.xml) values/ 纯数值资源(strings.xml colors.xml dimens.xml) values-night/ 夜间模式的同名资源覆盖
引用语法统一是 @类型/名字,名字就是去扩展名的文件名(或 values 文件里的条目名):
android:text="@string/btn_guess" android:src="@drawable/ic_face_smile" android:textSize="@dimen/body_size"
代码侧则是 R 类静态常量:R.string.btn_guess、R.drawable.ic_face_smile。编译器把整个 res 目录编成一张表,引用一个不存在的资源是编译错误而不是运行时崩溃——这是资源体系给的第一份安全感,拼写错误当场暴露。
命名禁令也由此而来:资源名只能用小写字母、数字与下划线,icFaceSmile 或 guess-btn 都是编译报错。习惯上给名字加类型前缀(ic_ 图标、bg_ 背景、btn_ 按钮样式、tv_ 控件 id),整个项目的资源表一眼可读。
values 目录的特别之处在于合并语义:strings.xml、colors.xml、dimens.xml 甚至更多文件里的同名条目会合并进同一个命名空间。这意味着文件名只是给人看的分册,机器眼里只有 @string/xxx 这个 id——理论上你可以全塞进一个文件,分成多文件纯粹是为了人的可维护性。标准分册:
<!-- strings.xml:一切用户可见文字 --> <string name="btn_guess">提交猜测</string> <string name="hint_input">输入 1 到 100 之间的整数</string> <!-- colors.xml:颜色 --> <color name="primary">#3F51B5</color> <!-- dimens.xml:尺寸 --> <dimen name="body_size">16sp</dimen> <dimen name="screen_padding">16dp</dimen>
把用户可见文字全收进 strings.xml 不是洁癖:应用名改版、多语言翻译(values-zh、values-en 目录按语言限定词生效)都依赖这一步集中。硬编码在布局里的中文,翻译时就是漏网之鱼。
目录名加横线后缀就是限定词,系统按设备环境挑选最合适的版本。夜间模式是最常用的一种——values-night/colors.xml 里放同名深色条目,黑暗降临自动生效:
<!-- values-night/colors.xml --> <color name="page_bg">#121212</color> <color name="text_main">#E0E0E0</color>
布局不用改一行,引用 @color/page_bg 的地方自动换肤。同理 drawable-hdpi 到 drawable-xxxhdpi 按屏幕密度选图;mipmap 专门放启动图标是因为桌面启动器可能请求超密度图,它需要独立于 drawable 的密度桶。限定词的匹配优先级系统自动处理,入门阶段记住同名资源、多份环境版本、系统挑最合适的这个模型即可。

💡 Android Studio 的 Shannon 快捷面板(View 菜单 Tool Windows 找 Resource Manager)能可视化浏览全部 drawable 与颜色,比翻目录直观,重命名资源时记得用它带重构的 Rename,引用会同步更新。
@string/xxx。drawable 里的 xml 是什么? 打开它会发现里面不是位图而是矢量定义——一段描述路径与填色的 XML,任意密度下缩放不糊。现代项目的图标应尽量走矢量,只有照片类内容才需要按密度分桶的位图,这也是为什么 drawable 目录里 xml 文件越来越多的原因。
资源会不会越攒越乱? 会,所以要有清理纪律。Android Studio 的 lint 能扫出"无引用资源"清单,发布前跑一轮删干净;命名前缀体系建得越早,后期检索成本越低——资源表和代码一样,是需要持续整理的资产。
代码里能拿资源吗? 能,R 类常量就是为此而生:字符串用 getString、颜色用 ContextCompat.getColor、尺寸按类型各有取法。方向要记牢:布局里用 @ 引用、代码里用 R 引用,两套钥匙开同一扇门。
还有一个编译期行为值得单独点出:资源引用拼错是编译失败而不是运行崩溃,但反射式取资源(用字符串拼资源名动态取 id)会绕过这层保护,退回运行时风险。入门阶段的原则很简单:永远用 R 常量与 @ 引用,让编译器站岗。