在这里插入图片描述
在这里插入图片描述

1 项目概述

1.1 应用简介

油价查询应用是一款面向车主的实用工具,主要提供国内油价信息的查询服务。油价是车主日常用车成本的重要组成部分,其波动直接影响出行开支。车主经常需要了解当前的油价水平,以便合理安排加油时机、计算出行成本。油价查询应用正是为了满足这类信息需求而设计,用户可以快速查看各类油品的最新价格。

本应用采用 HarmonyOS 平台的 ArkUI 声明式开发框架,基于 ArkTS 语言实现。应用采用卡片式列表设计,用户点击"加载油价"按钮后可以查看今日各类型油品的最新价格。价格信息包括油品名称、单价和计量单位,结构清晰,便于快速浏览和对比。

1.2 技术架构分析

本应用采用单页面架构设计,OilPrice 组件作为 @Entry 入口组件,集中实现了所有的业务功能。页面结构清晰,从上到下依次为标题栏、今日油价概览区、油价列表展示区。

import { CommonTitleBar } from '../../components/CommonTitleBar';

@Entry
@Component
struct OilPrice {
  @State app_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
@Component
struct OilPrice {
  @State app_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 油价数据模型

@State app_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(计量单位)三个字段。

在实际应用中,建议使用更严格的类型定义:

interface OilPrice {
  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 开发中的优势。开发者只需描述"界面应该呈现什么数据",框架会自动处理状态变化时的界面更新。这种编程范式降低了出错概率,提高了开发效率。

期待在后续的迭代中,油价查询应用能够接入真实的油价数据,增加历史走势、加油站在线等功能,为车主的日常用车提供更全面的服务。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐