1 项目概述
1.1 应用简介
油价查询应用是一款面向车主的实用工具,主要提供国内油价信息的查询服务。油价是车主日常用车成本的重要组成部分,其波动直接影响出行开支。车主经常需要了解当前的油价水平,以便合理安排加油时机、计算出行成本。油价查询应用正是为了满足这类信息需求而设计,用户可以快速查看各类油品的最新价格。
本应用采用 HarmonyOS 平台的 ArkUI 声明式开发框架,基于 ArkTS 语言实现。应用采用卡片式列表设计,用户点击"加载油价"按钮后可以查看今日各类型油品的最新价格。价格信息包括油品名称、单价和计量单位,结构清晰,便于快速浏览和对比。
1.2 技术架构分析
本应用采用单页面架构设计,OilPrice 组件作为 @Entry 入口组件,集中实现了所有的业务功能。页面结构清晰,从上到下依次为标题栏、今日油价概览区、油价列表展示区。
import{CommonTitleBar}from'../../components/CommonTitleBar';@Entry@Componentstruct OilPrice{@Stateapp_oilPrices:Record<string,string>[]=[];build(){Column(){CommonTitleBar({app_title:'油价查询',app_showBack:true})Column({space:16}){// 今日油价概览区Column({space:8}){Text('今日油价')Text('更新时间: 2024-01-15')}// 加载按钮Button('加载油价')// 油价列表List(){ForEach(this.app_oilPrices,(app_oil:Record<string,string>)=>{ListItem(){Row(){// 油品名称Column(){Text(app_oil['type'])}// 价格信息Column(){Text(app_oil['price']),Text(app_oil['unit'])}}}})}}}}}应用使用 @State 装饰器管理油价列表数据。当用户点击加载按钮时,状态变量被更新为包含多条油品数据的数组,List 组件自动重新渲染展示最新的油价信息。
1.3 核心功能特性
油价查询应用的核心功能设计围绕信息展示和交互反馈展开:
油价概览展示:页面顶部设置今日油价概览区,显示标题"今日油价"和更新时间。概览区采用白色卡片设计,与页面背景形成层次对比。
一键加载操作:中央设置"加载油价"按钮,用户点击后触发数据加载逻辑,更新油价列表显示。按钮设计简洁明了,操作路径短。
油品列表展示:主内容区域使用 List 组件展示各类型油品的价格信息。每条油品数据包括油品类型、单价和计量单位,信息完整且层次清晰。
价格醒目展示:单价数字使用较大字号和加粗字体突出显示,便于用户快速获取核心信息。计量单位使用较小字号和辅助颜色,作为价格信息的补充说明。
2 核心代码模块详解
2.1 组件状态定义模块
@Entry@Componentstruct OilPrice{@Stateapp_oilPrices:Record<string,string>[]=[];build(){// build 方法内容}}OilPrice 组件使用 @Entry 装饰器标识为页面入口组件。组件内部定义了 @State 状态变量 app_oilPrices,类型为Record<string, string>[],用于存储油品价格数据列表。
数据类型设计:Record<string, string> 是 ArkTS 内置的泛型类型,表示键值对对象。这里使用它存储每条油品数据的属性键值对。
初始状态:变量初始化为空数组[],表示页面初始时没有显示任何油价数据。用户在初始状态下看到的是概览区域和加载按钮,列表为空。
响应式特性:@State 装饰器将数组变量转换为响应式状态。当执行赋值操作this.app_oilPrices = [...]时,ArkUI 框架会自动检测到状态引用变化,触发 List 组件重新渲染。
2.2 今日油价概览模块
Column({space:8}){Text('今日油价').fontSize(18).fontWeight(FontWeight.Bold).fontColor($r('app.color.app_color_text_primary')).width('100%')Text('更新时间: 2024-01-15').fontSize(12).fontColor($r('app.color.app_color_text_tertiary')).width('100%')}.width('100%').padding(16).backgroundColor($r('app.color.app_color_white')).borderRadius(12)今日油价概览区位于页面主体内容的顶部,起到信息聚合和状态说明的作用。
标题设计:主标题"今日油价"使用 18sp 加粗字体,是页面中字号最大的标题元素。加粗字体突出了区域主题,让用户快速识别当前查看的内容类别。
时间戳设计:更新时间使用 12sp 较小字体和三级文字颜色,作为辅助说明信息。时间戳的设计体现了信息的时效性,提醒用户数据的有效期限。
容器样式:外层 Column 设置 width(‘100%’) 占据可用宽度,padding(16) 提供内边距空间。backgroundColor 设置为白色,borderRadius 设置为 12dp 圆角,呈现出卡片式的视觉效果。
2.3 加载按钮模块
Button('加载油价').width('100%').onClick(()=>{this.app_oilPrices=[{'type':'92号汽油','price':'7.56','unit':'元/升'},{'type':'95号汽油','price':'8.06','unit':'元/升'},{'type':'98号汽油','price':'9.26','unit':'元/升'},{'type':'0号柴油','price':'7.28','unit':'元/升'}];})加载按钮是用户触发数据加载操作的核心交互入口。按钮文字"加载油价"清晰表达了操作结果,用户点击后可以获取最新的油价数据。
按钮样式:按钮宽度设置为 100%,占据整个内容区域宽度。按钮样式采用 ArkUI 的默认样式,主题色背景配白色文字。
数据模拟:onClick 回调中硬编码了四条油品数据作为模拟。这四条数据覆盖了常见的油品类型:92号汽油(常见家用车使用)、95号汽油(部分中高端车型使用)、98号汽油(高端车型使用)、0号柴油(柴油车使用)。
数据结构解析:每条油品数据包含三个字段:
| 字段 | 含义 | 示例值 |
|---|---|---|
| type | 油品类型名称 | ‘92号汽油’ |
| price | 单价 | ‘7.56’ |
| unit | 计量单位 | ‘元/升’ |
2.4 油价列表渲染模块
List(){ForEach(this.app_oilPrices,(app_oil:Record<string,string>)=>{ListItem(){Row(){Column({space:4}){Text(app_oil['type']).fontSize(16).fontWeight(FontWeight.Medium).fontColor($r('app.color.app_color_text_primary'))}Blank()Column({space:4}){Text(app_oil['price']).fontSize(24).fontWeight(FontWeight.Bold).fontColor($r('app.color.app_color_danger'))Text(app_oil['unit']).fontSize(12).fontColor($r('app.color.app_color_text_tertiary'))}}.width('100%').padding(12).backgroundColor($r('app.color.app_color_white')).borderRadius(8)}})}.width('100%').layoutWeight(1)油价列表渲染模块是应用的核心 UI 部分,展示了各类油品的完整价格信息。这段代码涉及 List、ForEach、Row、Column 等多个 ArkUI 组件的组合使用。
List 组件:List 是专门用于长列表渲染的组件,提供内置的滚动机制和虚拟化渲染能力。layoutWeight(1) 设置使其占据主内容区域的剩余空间,当油品数量超出屏幕范围时用户可以上下滚动查看。
ForEach 循环渲染:ForEach 组件遍历 app_oilPrices 数组,为每个油品生成一个 ListItem。ForEach 是声明式 UI 的核心概念,开发者只需描述"对于每个油品应该渲染什么",框架会自动处理渲染和更新逻辑。
列表项布局:列表项内部使用 Row 水平布局,左侧是油品名称,右侧是价格和单位信息。Blank 组件用于填充中间空间,将右侧价格信息推到最边缘,实现左右分布的效果。
信息层级设计:
| 元素 | 字号 | 字重 | 颜色 | 作用 |
|---|---|---|---|---|
| 油品名称 | 16sp | Medium | 主要文字 | 识别油品类型 |
| 价格数字 | 24sp | Bold | 危险色/强调色 | 突出核心数据 |
| 计量单位 | 12sp | Normal | 三级文字 | 补充说明 |
价格颜色:价格数字使用 app_color_danger(#FF4D4F)危险色/强调色渲染,这种设计突出了价格信息的重要性。在银行、金融类应用中,红色常用于表示金额数字,便于用户快速定位关键数据。
容器样式:列表项设置 backgroundColor 为白色,borderRadius 为 8dp 圆角,呈现出卡片式的视觉效果。相邻列表项之间依靠背景色的连续性形成视觉边界。
3 界面布局与交互设计
3.1 整体布局架构
油价查询应用的界面布局采用垂直分布的结构:
┌────────────────────────────────────┐ │ 通用标题栏 │ │ [返回] 油价查询 [空白] │ ├────────────────────────────────────┤ │ │ │ ┌──────────────────────────────┐ │ │ │ 今日油价 │ │ <- 概览区 │ │ 更新时间: 2024-01-15 │ │ │ └──────────────────────────────┘ │ │ │ │ ┌──────────────────────────────┐ │ │ │ [ 加载油价 ] │ │ <- 操作按钮 │ └──────────────────────────────┘ │ │ │ │ ┌──────────────────────────────┐ │ │ │ 92号汽油 7.56 │ │ │ │ 元/升 │ │ <- 列表项 │ └──────────────────────────────┘ │ │ ┌──────────────────────────────┐ │ │ │ 95号汽油 8.06 │ │ │ │ 元/升 │ │ │ └──────────────────────────────┘ │ │ ┌──────────────────────────────┐ │ │ │ 98号汽油 9.26 │ │ │ │ 元/升 │ │ │ └──────────────────────────────┘ │ │ ┌──────────────────────────────┐ │ │ │ 0号柴油 7.28 │ │ │ │ 元/升 │ │ │ └──────────────────────────────┘ │ │ │ └────────────────────────────────────┘页面整体使用垂直布局(Column),由上到下依次是标题栏、今日油价概览区、加载按钮、油价列表。背景使用浅灰色 (#F5F5F5),内容卡片使用白色,形成清晰的视觉层次。
3.2 列表设计要点
List 组件是油价查询应用中最重要的 UI 组件,与停车场应用中的列表类似,List 采用了虚拟化渲染机制,只渲染当前可见区域内的列表项。
List(){ForEach(this.app_oilPrices,(app_oil:Record<string,string>)=>{ListItem(){// 列表项内容}})}.width('100%').layoutWeight(1)List 的 layoutWeight(1) 设置是实现正确布局的关键。如果不设置 layoutWeight,List 的高度会由其内容决定,失去滚动能力。设置 layoutWeight 后,List 会占据父容器分配的所有剩余空间,并在内容超出时启用滚动。
3.3 交互流程设计
初始状态:用户进入应用后,看到今日油价概览区和"加载油价"按钮。列表区域初始为空,因为 app_oilPrices 是空数组。概览区显示"今日油价"标题和固定的更新时间。
加载交互:用户点击"加载油价"按钮后,按钮的 onClick 回调执行,更新 app_oilPrices 状态变量为包含四条油品数据的数组。ArkUI 检测到状态变化后,自动触发 List 组件重新渲染。
列表浏览:数据加载完成后,用户可以浏览各类型油品的价格信息。价格数字使用醒目的红色加粗字体,便于快速识别。列表支持滚动,当油品数量较多时可以查看全部内容。
数据感知:用户通过价格的高低可以判断当前油价水平。列表按照 92号、95号、98号汽油和0号柴油的顺序排列,这个顺序符合大多数用户的认知习惯。
4 数据结构设计
4.1 油价数据模型
@Stateapp_oilPrices:Record<string,string>[]=[{'type':'92号汽油','price':'7.56','unit':'元/升'},{'type':'95号汽油','price':'8.06','unit':'元/升'},{'type':'98号汽油','price':'9.26','unit':'元/升'},{'type':'0号柴油','price':'7.28','unit':'元/升'}];Record<string, string> 类型表示一个键值对对象,键和值都是字符串类型。每条油品数据包含 type(油品类型)、price(单价)、unit(计量单位)三个字段。
在实际应用中,建议使用更严格的类型定义:
interfaceOilPrice{type:string;// 油品类型price:number;// 单价(元/升)unit:string;// 计量单位province?:string;// 省份(可选,支持分省油价)updateTime?:string;// 更新时间(可选)}TypeScript 的接口类型可以提供编译时的类型检查,帮助开发者发现潜在的类型错误。
4.2 模拟数据设计
模拟数据包含四种常见油品,覆盖了国内主要的油品类型:
| 油品类型 | 单价(元/升) | 计量单位 | 适用车型 |
|---|---|---|---|
| 92号汽油 | 7.56 | 元/升 | 普通家用车 |
| 95号汽油 | 8.06 | 元/升 | 部分中高端车型 |
| 98号汽油 | 9.26 | 元/升 | 高端车型 |
| 0号柴油 | 7.28 | 元/升 | 柴油车 |
这种数据设计覆盖了不同的价格区间,便于测试价格展示的视觉效果。价格数值仅供参考,不代表实际的油价水平。
4.3 状态数据流转
用户点击按钮 ↓ onClick 回调执行 ↓ app_oilPrices 赋值 ↓ ArkUI 状态追踪检测到变化 ↓ 触发 ForEach 重新渲染 ↓ List 更新列表项ArkUI 的响应式系统基于装饰器和观察者模式实现。当 @State 变量被赋值时,框架会标记受影响的作用域为"脏"状态,并在下一个渲染帧中重新渲染这些区域。
5 组件化设计实践
5.1 CommonTitleBar 组件应用
CommonTitleBar({app_title:'油价查询',app_showBack:true})CommonTitleBar 是项目中的通用标题栏组件,被多个页面共享使用。组件通过参数控制标题文字和返回按钮的显示,适应不同页面的需求。
统一外观:所有使用 CommonTitleBar 的页面都有一致的标题栏样式,包括高度(56vp)、背景色(主题色)、文字样式等。
可配置性:app_title 属性允许设置不同的页面标题,app_showBack 属性控制在首页等不需要返回的场景下隐藏按钮。
5.2 List 组件深度解析
List 是 ArkUI 框架提供的高性能列表组件,专为长列表场景设计:
虚拟化渲染:List 只渲染当前可见区域内的列表项,当用户滚动时动态复用和更新列表项。
内置滚动:List 自动提供滚动条和滚动手势支持,无需额外处理滚动逻辑。
布局属性:List 使用 layoutWeight(1) 占据父容器剩余空间,这是实现正确滚动行为的关键设置。
List(){ForEach(this.app_oilPrices,(app_oil:Record<string,string>)=>{ListItem(){// 列表项内容}})}.width('100%').layoutWeight(1)5.3 ForEach 与列表渲染
ForEach 组件是 ArkUI 声明式渲染的核心,每个列表项都通过 ForEach 动态生成:
ForEach(this.app_oilPrices,(app_oil:Record<string,string>)=>{ListItem(){Row(){Column({space:4}){Text(app_oil['type'])}Blank()Column({space:4}){Text(app_oil['price'])Text(app_oil['unit'])}}.padding(12).backgroundColor($r('app.color.app_color_white')).borderRadius(8)}})ForEach 自动追踪数据源的变化,当 app_oilPrices 被更新时,框架会自动重新渲染列表。
6 样式与主题系统
6.1 颜色资源体系
应用的颜色资源在 color.json 中定义:
{"color":[{"name":"app_color_primary","value":"#007DFF"},{"name":"app_color_success","value":"#52C41A"},{"name":"app_color_danger","value":"#FF4D4F"},{"name":"app_color_warning","value":"#FAAD14"},{"name":"app_color_background","value":"#F5F5F5"},{"name":"app_color_white","value":"#FFFFFF"}]}油价查询应用中主要使用以下颜色:
| 颜色 | 用途 |
|---|---|
| app_color_primary | 主题色、按钮 |
| app_color_danger | 价格数字(红色强调) |
| app_color_background | 页面背景 |
| app_color_white | 卡片背景 |
| app_color_text_primary | 主要文字 |
| app_color_text_tertiary | 辅助信息 |
6.2 字体规范
应用的字体使用遵循以下规范:
| 场景 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 标题栏标题 | 20sp | Bold | 白色 |
| 概览区标题 | 18sp | Bold | 主要文字 |
| 概览区时间 | 12sp | Normal | 三级文字 |
| 油品名称 | 16sp | Medium | 主要文字 |
| 价格数字 | 24sp | Bold | 强调色/红色 |
| 计量单位 | 12sp | Normal | 三级文字 |
6.3 间距与圆角
应用的间距系统基于 8dp 网格:
| 场景 | 间距值 |
|---|---|
| 主内容区内边距 | 16dp |
| 元素之间间距 | 8-16dp |
| 列表项内边距 | 12dp |
| 概览区卡片圆角 | 12dp |
| 列表项卡片圆角 | 8dp |
7 项目结构与组织
7.1 目录结构规范
entry/src/main/ets/ ├── components/ # 公共UI组件 │ ├── CommonTitleBar.ets # 通用标题栏 │ ├── CommonButton.ets # 通用按钮 │ ├── CommonCard.ets # 通用卡片 │ └── CommonList.ets # 通用列表 ├── pages/ │ ├── life/ # 生活服务类页面 │ │ ├── OilPrice.ets # 油价查询应用 │ │ ├── ParkingLot.ets # 停车场应用 │ │ ├── BusQuery.ets # 公交查询 │ │ ├── MetroNavigation.ets # 地铁导航 │ │ └── TaxiHelper.ets # 打车助手 │ └── ... └── ...生活服务类的页面集中在 pages/life 目录下,便于按功能模块管理和查找代码。
7.2 命名规范
项目使用统一的命名规范:
- 页面组件文件:
OilPrice.ets(帕斯卡命名) - 状态变量:
app_oilPrices(app_ 前缀 + 驼峰命名)
这种命名规范确保了代码的可读性和可维护性,团队成员可以快速理解代码的用途和范围。
8 扩展方向与优化建议
8.1 功能增强方向
分省油价查询:支持按省份查询油价,不同地区的油价可能存在差异。增加省份选择器,用户可以选择目标省份查看当地油价。
历史油价走势:增加历史油价图表,展示油价的变化趋势。可以用折线图展示近期的油价走势,帮助用户判断油价走势。
油价提醒:增加到油价下降或低于某阈值时的提醒功能。用户设置目标价格后,当油价达到目标时收到通知提醒。
加油站查找:集成附近加油站查询功能,用户不仅可以查看油价,还可以查找附近哪些加油站有优惠。
油耗计算:增加油耗计算工具,用户输入油耗和里程,计算总加油费用。
8.2 UI/UX 优化方向
下拉刷新:增加下拉刷新手势,用户可以下拉列表触发数据重新加载,获取最新油价。
骨架屏:为加载过程设计骨架屏,在数据加载中显示占位内容,避免界面突兀变化。
油品对比:增加对比功能,用户可以选择多个油品进行价格对比。
详情展开:点击列表项可以展开查看更详细的信息,如该油品的品质等级、适用车型建议等。
8.3 技术架构演进
数据层分离:将数据获取逻辑从 UI 组件中分离,封装到独立的数据服务层。
缓存机制:增加数据缓存机制,在一定时间内复用已加载的数据,减少重复请求。
状态管理升级:引入 AppStorage 进行全局状态管理,支持跨组件、跨页面的状态共享和持久化。
9 总结
油价查询应用是 HarmonyOS 平台上功能完整的工具类应用,展示了声明式 UI 开发的核心模式和最佳实践。通过本应用,我们深入学习了 List 组件的使用、ForEach 列表渲染、响应式状态管理以及信息展示的层次设计等技术点。
应用采用组件化架构设计,CommonTitleBar 提供统一的标题栏功能,List 组件提供高效的列表渲染能力,@State 装饰器实现响应式状态管理。这些技术点的组合构成了完整的列表类应用开发范式。
油价查询应用的数据展示设计具有参考价值。价格数字使用醒目的红色加粗字体,便于用户快速识别核心数据。油品类型、价格、单位采用不同的字号和字重,形成清晰的信息层次。
ArkUI 的声明式编程范式再次展示了其在 UI 开发中的优势。开发者只需描述"界面应该呈现什么数据",框架会自动处理状态变化时的界面更新。这种编程范式降低了出错概率,提高了开发效率。
期待在后续的迭代中,油价查询应用能够接入真实的油价数据,增加历史走势、加油站在线等功能,为车主的日常用车提供更全面的服务。