HarmonyOS 资源系统完全指南:$r() 引用、资源限定符与多分辨率适配
文章目录前言一、资源目录结构1.1 resources 目录1.2 本项目资源引用分析二、屏幕单位vp、fp、px 的区别2.1 三种单位说明2.2 为什么用 vp 而不是 px三、颜色资源与深色模式适配3.1 定义颜色资源3.2 系统颜色资源sys.color四、字符串资源与多语言4.1 定义字符串4.2 代码中获取字符串值五、图片资源与多密度适配5.1 不同密度的图片目录5.2 推荐使用 SVG 矢量图六、响应式布局平板适配总结前言一个优秀的 HarmonyOS 应用需要在不同屏幕尺寸手机/平板、不同屏幕密度标准/高清/超高清、不同主题浅色/深色下都能保持良好体验。这些都依赖资源管理系统的正确使用。本篇结合项目中$r(app.color.xxx)、$r(app.string.xxx)、$r(app.media.xxx)的使用系统讲解 HarmonyOS 资源体系。一、资源目录结构1.1 resources 目录entry/src/main/resources/ ├── base/ ← 默认资源所有设备 │ ├── element/ │ │ ├── color.json ← 颜色定义 │ │ ├── string.json ← 字符串 │ │ └── integer.json ← 整数常量 │ ├── media/ ← 图片/图标 │ │ ├── station.svg │ │ └── icon.png │ └── profile/ ← 配置文件路由映射等 │ └── route_map.json ├── dark/ ← 深色模式资源覆盖 base │ └── element/ │ └── color.json ← 深色模式颜色 ├── zh_CN/ ← 中文资源多语言 │ └── element/ │ └── string.json ├── en_US/ ← 英文资源 │ └── element/ │ └── string.json └── rawfile/ ← 原始文件不参与资源编译1.2 本项目资源引用分析// 颜色资源自动适配深色模式.backgroundColor($r(app.color.page_background)).backgroundColor($r(app.color.start_window_background)).fontColor($r(app.color.gas_station_name_color)).color($r(sys.color.mask_fourth))// ← sys.color 是系统提供的颜色// 字符串资源自动多语言Text($r(app.string.gas_station))Text($r(app.string.car_life))// 图片/图标资源Image($r(app.media.image1))Image($r(app.media.chevron_right))Image($r(app.media.back))二、屏幕单位vp、fp、px 的区别2.1 三种单位说明单位全称说明推荐场景vpVirtual Pixel虚拟像素与屏幕密度无关的逻辑像素ArkUI 默认单位布局尺寸、间距fpFont Pixel随系统字体大小设置缩放字体大小pxPhysical Pixel物理像素实际屏幕像素不同设备值不同尽量避免使用%百分比相对于父容器的百分比弹性布局// 推荐写法本项目的做法Text(加油站).fontSize(16)// 默认 fp 单位字体大小Column().width(200)// 默认 vp 单位布局宽度Row().height(100%)// 百分比// 等价显式写法Text(加油站).fontSize(16)// 等同于 16fpColumn().width(200vp)2.2 为什么用 vp 而不是 px低密度屏幕160dpi1vp 1px 标准密度屏幕320dpi1vp 2px 高密度屏幕480dpi1vp 3px 你写 200vp ─ 低密度屏幕显示 200px看起来一样大 ─ 高密度屏幕显示 600px看起来还是一样大 你写 200px ─ 低密度屏幕显示 200px正常 ─ 高密度屏幕显示 200px看起来只有正常大小的1/3超级小三、颜色资源与深色模式适配3.1 定义颜色资源resources/base/element/color.json{color:[{name:page_background,value:#F5F7FA},{name:start_window_background,value:#FFFFFF},{name:gas_station_name_color,value:#333333},{name:gas_station_addr_color,value:#999999},{name:bind_sheet_background,value:#F5F7FA}]}resources/dark/element/color.json深色模式覆盖{color:[{name:page_background,value:#1A1A1A},{name:start_window_background,value:#2C2C2C},{name:gas_station_name_color,value:#E0E0E0},{name:gas_station_addr_color,value:#888888},{name:bind_sheet_background,value:#252525}]}在代码中引用// 自动适配浅色模式用 base/color.json深色模式用 dark/color.json.backgroundColor($r(app.color.page_background)).fontColor($r(app.color.gas_station_name_color))3.2 系统颜色资源sys.color系统提供的语义化颜色在所有 HarmonyOS 应用中保持一致// 本项目使用的系统颜色.color($r(sys.color.mask_fourth))// 遮罩颜色自动适配深色模式// 其他常用系统颜色$r(sys.color.brand)// 品牌主色$r(sys.color.warning)// 警告色$r(sys.color.error)// 错误色$r(sys.color.font_primary)// 主文字色$r(sys.color.font_secondary)// 次要文字色$r(sys.color.background_primary)// 主背景色四、字符串资源与多语言4.1 定义字符串resources/base/element/string.json{string:[{name:gas_station,value:加油站},{name:car_life,value:车生活},{name:Stay_tuned,value:敬请期待},{name:calculate_text2,value:km},{name:reason_location,value:查找附近加油站需要您的位置信息}]}resources/en_US/element/string.json英文{string:[{name:gas_station,value:Gas Station},{name:car_life,value:Car Life},{name:Stay_tuned,value:Stay Tuned}]}在代码中引用// 自动根据系统语言选择对应翻译Text($r(app.string.gas_station))// 中文系统显示加油站英文系统显示Gas Station.title($r(app.string.car_life))// 中文显示车生活英文显示Car Life4.2 代码中获取字符串值// 在非 UI 代码中获取字符串如 Logger 输出conststationTextthis.getUIContext().getHostContext()?.resourceManager.getStringSync($r(app.string.gas_station).id);// stationText 加油站或当前语言对应值五、图片资源与多密度适配5.1 不同密度的图片目录resources/ ├── base/media/ │ └── icon.png ← 1x基准密度 ├── mdpi/media/ ← 1xMedium DPI160dpi │ └── icon.png ├── hdpi/media/ ← 1.5xHigh DPI240dpi │ └── icon.png ├── xhdpi/media/ ← 2xExtra High DPI320dpi │ └── icon.png └── xxhdpi/media/ ← 3x480dpi └── icon.png系统自动根据设备屏幕密度选择对应目录的图片。5.2 推荐使用 SVG 矢量图// SVG 矢量图在任何密度下都清晰不需要多套图Image($r(app.media.chevron_right))// 如果是 svg一套搞定所有密度.width(16).height(16)// PNG 位图需要提供多套或使用较大尺寸Image($r(app.media.station))// station.svg本项目用了 SVG本项目的station.svg用作地图 Marker 图标SVG 格式在任何缩放比例下都保持清晰——这是一个正确的设计选择。六、响应式布局平板适配EntryComponentstruct ResponsiveLayout{StorageProp(deviceType)deviceType:stringphone;build(){if(this.deviceTypetablet){// 平板两栏布局Row(){// 左栏加油站列表Column(){Text(加油站列表).fontSize(16).padding(16)}.width(40%).height(100%).backgroundColor(#FFFFFF)Divider().vertical(true).height(100%)// 右栏地图Column(){Text(地图区域).fontSize(16).padding(16)}.layoutWeight(1).height(100%).backgroundColor(#F5F7FA)}}else{// 手机单栏布局Column(){Text(手机版布局单栏).fontSize(16).padding(16)}.width(100%).height(100%)}}}总结HarmonyOS 资源系统通过资源限定符目录实现对不同设备、不同密度、不同语言的自动适配深色模式用dark/目录英文用en_US/目录高密度用xhdpi/目录。始终使用vp而非px作为布局单位使用$r()引用资源而非硬编码字符串使用 SVG 矢量图代替多套 PNG这三点是 HarmonyOS 多端适配的核心原则。