当前位置: 首页 > news >正文

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)// 等同于 '16fp'Column().width('200vp')

2.2 为什么用 vp 而不是 px?

低密度屏幕(160dpi):1vp = 1px 标准密度屏幕(320dpi):1vp = 2px 高密度屏幕(480dpi):1vp = 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 Life"

4.2 代码中获取字符串值

// 在非 UI 代码中获取字符串(如 Logger 输出)conststationText=this.getUIContext().getHostContext()?.resourceManager.getStringSync($r('app.string.gas_station').id);// stationText = '加油站'(或当前语言对应值)

五、图片资源与多密度适配

5.1 不同密度的图片目录

resources/ ├── base/media/ │ └── icon.png ← 1x(基准密度) ├── mdpi/media/ ← 1x(Medium DPI,160dpi) │ └── icon.png ├── hdpi/media/ ← 1.5x(High DPI,240dpi) │ └── icon.png ├── xhdpi/media/ ← 2x(Extra High DPI,320dpi) │ └── icon.png └── xxhdpi/media/ ← 3x(480dpi) └── 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 格式在任何缩放比例下都保持清晰——这是一个正确的设计选择。

六、响应式布局:平板适配

@Entry@Componentstruct ResponsiveLayout{@StorageProp('deviceType')deviceType:string='phone';build(){if(this.deviceType==='tablet'){// 平板:两栏布局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 多端适配的核心原则。

http://www.jsqmd.com/news/980592/

相关文章:

  • 2026心肺复苏模拟人定制品牌测评:国内厂家排名与高性价比选型指南 - 资讯速览
  • 豆包(SeeD)推理集群的核心运行骨架,所有AI应答、记忆留存、算力调度、安全防护全部依托这一套函数栈运转
  • LLM DLP实战手册:五层防护体系应对大模型PII泄露
  • 攀枝花防水补漏哪家靠谱?2026 正规修缮公司排名实测 - 苏易修缮
  • 算力网建设加速:打破资源壁垒,让算力像水电一样随取随用
  • 济南历下区黄金回收市场分析:识别乱象选对机构安全变现 - 上门黄金回收
  • 科研小白看过来:NoteExpress搭配Zotero/EndNote?我的文献管理组合拳实战分享
  • 别再死磕Altera了!手把手教你用AG256SL100国产CPLD替代EPM240T100C5N(附引脚兼容对照表)
  • 如何快速解决TranslucentTB无法启动:Windows任务栏透明工具完全指南
  • Java写的跨系统远程控制工具:网页看屏、键鼠操作、剪贴板互通、传文件
  • 领嵌iLeadE-588边缘计算盒子为AI推理、图像识别等场景提供强劲性能支持
  • 原神帧率解锁终极指南:轻松突破60FPS限制,畅享流畅游戏体验
  • 别再傻傻分不清了!嵌入式开发中SDRAM、DDR、NOR Flash和NAND Flash到底怎么选?
  • 【广州楼市研判系列05】2026广州楼市深度复盘:存量周期结构性修复提速,房产价值分层格局定型 - 资讯速览
  • 电路中 5 个核心幅度参数详解:定义、区别与典型应用
  • 2026填料厂家横评观察:供给链路、工艺成熟度与选型评估指南 - 企师傅推荐官
  • 2026最新AI大模型学习路线:(非常详细)AI大模型学习路径
  • 微信网页版访问:浏览器扩展如何破解访问限制
  • YOLOv1的‘快’从何而来?对比Faster R-CNN,聊聊单阶段检测的工程取舍与设计哲学
  • 别再让机械臂‘软趴趴’!CoppeliaSim动力学建模保姆级避坑指南(从STL导入到关节扭矩设置)
  • 网盘直链解析工具技术架构:基于Vert.x的高性能异步处理方案
  • CyberdropBunkrDownloader:告别繁琐操作,一键批量下载文件分享平台内容
  • 从零到百:我是如何利用GitHub Topics为我的开源项目吸引第一批贡献者的
  • Spring 零基础入门到进阶 基于 XML 管理 Bean 14-28
  • 全介质销毁设备合规与技术的双重保障安全性解析 - 奔跑123
  • 松江区排名第一・源头工厂店・伊伽依窗帘 希布软装・权威认证・明码实价・全屋布艺定制专家 - 花生花生1
  • 理论框架总搭不起来?高校导师推荐这几个AI论文工具
  • 新余防水补漏哪家靠谱?2026 正规修缮公司排名实测 - 苏易修缮
  • 别再死记硬背Modbus帧格式了!用STM32CubeMX+RS485,5分钟搞懂RTU通信流程
  • 进化算法工程落地手册:从失效现场到稳准快优化