03 HarmonyOS Next仪表盘案例详解(二):进阶篇

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!

文章目录

    • 前言
    • 1. 响应式设计
      • 1.1 屏幕适配
      • 1.2 弹性布局
    • 2. 数据展示与交互
      • 2.1 数据卡片渲染
      • 2.2 图表区域
    • 3. 事件处理机制
      • 3.1 点击事件处理
      • 3.2 手势交互
    • 4. 性能优化技巧
      • 4.1 懒加载与按需渲染
      • 4.2 状态管理优化
    • 5. 数据流管理
      • 5.1 单向数据流
      • 5.2 响应式数据绑定
    • 6. 最佳实践
      • 6.1 组件化开发
      • 6.2 样式与逻辑分离
    • 7. 总结

前言

关于HarmonyOS NEXT 的仪表盘 从

    1. HarmonyOS应用开发实践与技术解析
    1. HarmonyOS Next仪表盘案例详解(一):基础篇
      再到本章节 就已经全部讲完了, 接下来我们先展示一下其运行的效果

首页List

效果演示

1. 响应式设计

1.1 屏幕适配

// 获取屏幕宽度
this.screenWidth = px2vp(AppStorage.Get<number>('windowWidth') || 720)// 根据屏幕宽度决定每行显示的卡片数量
Flex({ wrap: FlexWrap.Wrap, justifyContent: this.screenWidth > 600 ? FlexAlign.Start : FlexAlign.SpaceAround })// 卡片宽度自适应
.width(this.screenWidth > 600 ? '22%' : '45%')

案例中通过检测屏幕宽度实现响应式布局:

  • 当屏幕宽度大于600像素时,每行显示4个卡片,宽度为22%
  • 当屏幕宽度小于等于600像素时,每行显示2个卡片,宽度为45%

这种响应式设计使应用能够在不同尺寸的设备上提供良好的用户体验。

1.2 弹性布局

Flex({ wrap: FlexWrap.Wrap, justifyContent: this.screenWidth > 600 ? FlexAlign.Start : FlexAlign.SpaceAround })

使用Flex组件的wrap属性实现卡片的自动换行,并根据屏幕宽度动态调整对齐方式:

  • 宽屏设备:左对齐(FlexAlign.Start)
  • 窄屏设备:均匀分布(FlexAlign.SpaceAround)

2. 数据展示与交互

2.1 数据卡片渲染

ForEach(this.dataCards, (card: DashboardCardItem) => {// 数据卡片Column() {// 卡片标题Text(card.title).fontSize(14).fontColor('#666').margin({bottom: 12})// 数据值和单位Flex({alignItems: ItemAlign.Baseline}) {Text(card.value).fontSize(28).fontWeight(FontWeight.Bold).fontColor(card.color)Text(card.unit).fontSize(14).fontColor(card.color).margin({left: 4})}.margin({bottom: 8})// 趋势指标Text(card.trend).fontSize(14).fontColor(card.trend.includes('+') ? '#2A9D8F' : '#E76F51')}// 卡片样式...
})

使用ForEach循环渲染数据卡片,每个卡片包含标题、数值、单位和趋势指标。根据趋势的正负动态设置颜色:

  • 正向趋势(+):绿色(#2A9D8F)
  • 负向趋势(-):红色(#E76F51)

2.2 图表区域

// 图表区域(示意)
Column() {Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {Text('销售趋势分析').fontSize(18).fontWeight(FontWeight.Medium)Flex() {ForEach(['日', '周', '月', '年'], (item: string) => {Text(item).fontSize(14).fontColor(item === '周' ? '#007DFF' : '#666').backgroundColor(item === '周' ? '#E6F1FF' : 'transparent').height(32).width(40).textAlign(TextAlign.Center).borderRadius(16)})}}// ...// 图表占位区域Column() {Text('此处放置销售趋势图表').fontSize(14).fontColor('#999')}// ...
}

图表区域包含标题栏和时间筛选器,通过ForEach循环渲染日、周、月、年四个选项,并高亮显示当前选中的"周"选项。这种设计允许用户快速切换不同时间维度的数据视图。

3. 事件处理机制

3.1 点击事件处理

ForEach(['日', '周', '月', '年'], (item: string) => {Text(item).fontSize(14).fontColor(item === this.timeRange ? '#007DFF' : '#666').backgroundColor(item === this.timeRange ? '#E6F1FF' : 'transparent').height(32).width(40).textAlign(TextAlign.Center).borderRadius(16).onClick(() => {// 更新选中的时间范围this.timeRange = item// 根据新的时间范围更新图表数据this.updateChartData()})
})

通过onClick事件处理器实现交互功能,当用户点击不同的时间选项时:

  1. 更新当前选中的时间范围状态变量
  2. 调用更新图表数据的方法,刷新图表显示

3.2 手势交互

// 图表区域手势交互
GestureGroup({// 同时识别多种手势type: GestureType.Parallel,// 手势之间的关系gestures: [PanGesture({ direction: PanDirection.Horizontal }).onActionStart((event: GestureEvent) => {// 记录起始位置this.startX = event.offsetX}).onActionUpdate((event: GestureEvent) => {// 计算拖动距离,更新图表显示范围let offsetX = event.offsetX - this.startXthis.updateChartViewport(offsetX)}),PinchGesture().onActionUpdate((event: GestureEvent) => {// 根据缩放比例调整图表显示范围this.updateChartScale(event.scale)})]
})

实现了两种手势交互:

  • 平移手势(PanGesture):允许用户左右滑动查看不同时间段的数据
  • 捏合手势(PinchGesture):允许用户通过捏合操作放大或缩小图表视图

4. 性能优化技巧

4.1 懒加载与按需渲染

LazyForEach(this.dataSource, (item: DataItem) => {// 数据项渲染逻辑DataItemComponent({ data: item })
})

使用LazyForEach代替ForEach进行大量数据的渲染,实现按需加载,提高应用性能:

  • 只渲染可见区域的数据项
  • 当用户滚动时,动态加载新的数据项
  • 释放不可见区域的资源

4.2 状态管理优化

// 使用AppStorage全局状态管理
aboutToAppear() {// 订阅全局状态变化this.dashboardDataSubscriber = AppStorage.Subscribe('dashboardData', (data: DashboardData) => {// 仅在数据变化时更新UIif (JSON.stringify(data) !== JSON.stringify(this.localData)) {this.localData = datathis.updateUI()}})
}aboutToDisappear() {// 取消订阅,避免内存泄漏this.dashboardDataSubscriber.unsubscribe()
}

通过状态管理优化提高应用性能:

  • 使用AppStorage进行全局状态管理
  • 实现数据变化的细粒度检测,避免不必要的UI更新
  • 组件销毁时取消订阅,防止内存泄漏

5. 数据流管理

5.1 单向数据流

// 父组件
@State dashboardData: DashboardData = initialDatabuild() {Column() {// 将数据通过属性传递给子组件DataCards({ data: this.dashboardData.cards })ChartSection({ data: this.dashboardData.chartData,// 传递回调函数处理子组件事件onTimeRangeChange: (range) => this.updateTimeRange(range)})}
}// 子组件
@Component
struct DataCards {// 使用@Prop接收父组件传递的数据@Prop data: CardData[]build() {// 渲染逻辑}
}

实现单向数据流模式:

  • 父组件维护应用状态
  • 通过属性将数据传递给子组件
  • 子组件通过回调函数将事件传递给父组件
  • 父组件处理事件并更新状态,触发UI更新

5.2 响应式数据绑定

// 定义响应式状态
@State selectedTimeRange: string = '周'
@State chartData: ChartDataPoint[] = []// 计算属性
@Computed get filteredData(): ChartDataPoint[] {return this.chartData.filter(item => {// 根据选中的时间范围过滤数据if (this.selectedTimeRange === '日') {return item.date.startsWith(this.currentDay)} else if (this.selectedTimeRange === '周') {return this.isInCurrentWeek(item.date)}// 其他条件...})
}build() {Column() {// 使用计算属性自动更新UIChartComponent({ data: this.filteredData })}
}

利用ArkTS的响应式特性:

  • 使用@State声明响应式状态
  • 使用@Computed定义计算属性,自动响应状态变化
  • 状态变化时自动触发UI更新,无需手动干预

6. 最佳实践

6.1 组件化开发

// 抽取数据卡片为独立组件
@Component
struct DataCard {@Prop cardData: DashboardCardItembuild() {Column() {Text(this.cardData.title).fontSize(14).fontColor('#666').margin({bottom: 12})Flex({alignItems: ItemAlign.Baseline}) {Text(this.cardData.value).fontSize(28).fontWeight(FontWeight.Bold).fontColor(this.cardData.color)Text(this.cardData.unit).fontSize(14).fontColor(this.cardData.color).margin({left: 4})}.margin({bottom: 8})Text(this.cardData.trend).fontSize(14).fontColor(this.cardData.trend.includes('+') ? '#2A9D8F' : '#E76F51')}.width('100%').padding(16).backgroundColor('#FFFFFF').borderRadius(12)}
}// 在主组件中使用
ForEach(this.dataCards, (card: DashboardCardItem) => {DataCard({ cardData: card })
})

组件化开发的优势:

  • 提高代码复用率
  • 简化主组件逻辑
  • 便于维护和测试
  • 支持团队协作开发

6.2 样式与逻辑分离

// 样式常量
const CARD_STYLES = {container: {width: '100%',padding: 16,borderRadius: 12,backgroundColor: '#FFFFFF'},title: {fontSize: 14,fontColor: '#666',marginBottom: 12},// 其他样式...
}// 在组件中使用
@Component
struct StyledCard {@Prop data: CardDatabuild() {Column() {Text(this.data.title).fontSize(CARD_STYLES.title.fontSize).fontColor(CARD_STYLES.title.fontColor).margin({bottom: CARD_STYLES.title.marginBottom})// 其他UI元素...}.width(CARD_STYLES.container.width).padding(CARD_STYLES.container.padding).backgroundColor(CARD_STYLES.container.backgroundColor).borderRadius(CARD_STYLES.container.borderRadius)}
}

样式与逻辑分离的好处:

  • 提高代码可读性
  • 便于统一管理和修改样式
  • 支持主题切换
  • 减少重复代码

7. 总结

本文详细介绍了HarmonyOS仪表盘应用的进阶开发技巧,包括:

  1. 响应式设计:通过屏幕适配和弹性布局实现多设备适配
  2. 数据展示与交互:实现数据卡片渲染和图表区域的交互功能
  3. 事件处理机制:通过点击事件和手势交互增强用户体验
  4. 性能优化技巧:使用懒加载和状态管理优化提高应用性能
  5. 数据流管理:实现单向数据流和响应式数据绑定
  6. 最佳实践:采用组件化开发和样式与逻辑分离的开发模式

通过这些技巧,开发者可以构建出高性能、易维护且用户体验良好的HarmonyOS仪表盘应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python-leetcode-统计构造好字符串的方案数

2466. 统计构造好字符串的方案数 - 力扣&#xff08;LeetCode&#xff09; 这个问题可以用**动态规划&#xff08;DP&#xff09;**来解决&#xff0c;思路如下&#xff1a; 思路 1. 定义 DP 数组 设 dp[i] 表示长度为 i 的好字符串的个数。 2. 状态转移方程 我们可以在 dp…

MySQL------存储引擎和用户和授权

9.存储引擎 1.两种引擎 MyISAM和InnoDB 2.两种区别 1.事务&#xff1a; MyISAM不支持事务 2.存储文件: innodb : frm、ibd MyISAM: frm、MYD、MYI 3.数据行锁定: MyISAM不支持 4.全文索引: INNODB不支持&#xff0c;所以MYISAM做select操作速度很快 5.外键约束: MyISAM…

题海拾贝:P9241 [蓝桥杯 2023 省 B] 飞机降落

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

删除有序数组中的重复项(js实现,LeetCode:26)

给你一个 非严格递增排列 的数组 nums &#xff0c;请你原地删除重复出现的元素&#xff0c;使每个元素只出现一次&#xff0c;返回删除后数组的新长度。元素的相对顺序应该保持一致。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你需要做以…

3-9 WPS JS宏单元格复制、重定位应用(拆分单表到多表)

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…

大白话react第十六章React 与 WebGL 结合的实战项目

大白话react第十六章React 与 WebGL 结合的实战项目 1. 项目简介 React 是一个构建用户界面的强大库&#xff0c;而 WebGL 则允许我们在网页上实现高性能的 3D 图形渲染。将它们结合起来&#xff0c;我们可以创建出炫酷的 3D 网页应用&#xff0c;比如 3D 产品展示、虚拟场景…

【AI赋能】AI 工具生成视频教材:从创意到成品的全流程指南

AI 工具生成视频教材&#xff1a;从创意到成品的全流程指南 目标 通过本教材&#xff0c;您将学会如何利用 AI 工具&#xff08;Grok、Sora、Speechify 和 CapCut&#xff09;生成一个完整的视频&#xff0c;包括脚本生成、视频片段制作、字幕添加、音频生成以及最终剪辑合成…

C/C++蓝桥杯算法真题打卡(Day2)

一、面试题 08.01. 三步问题 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; class Solution { public:const int MOD 1e9 7;int waysToStep(int n) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回// 处理边界情况if (n 1 || n 2)return n;if (n 3)r…

腾讯云物联网平台(IoT Explorer)设备端使用

1、直接看图流程 2、跑起来demo,修改产品id,设备名称,设备秘钥。 3、连接部分 4、修改默认地址和端口 sdk里面的地址默认是带着产品ID拼接的,咱们现在中铁没有泛域名解析,要改下这里。把+productID都去掉,然后地址里的.也去掉。

GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)

运行效果(音频) 简介 上一个教程演示了GStreamer工具。本教程介绍视频播放控制。快进、反向播放和慢动作都是技术 统称为 Trick Modes&#xff0c;它们都有一个共同点 修改 Normal playback rate。本教程介绍如何实现 这些效果并在交易中添加了帧步进。特别是&#xff0c;它 显…

Dify+DeepSeek | Excel数据一键可视化(创建步骤案例)(echarts助手.yml)(文档表格转图表、根据表格绘制图表、Excel绘制图表)

Dify部署参考&#xff1a;Dify Rag部署并集成在线Deepseek教程&#xff08;Windows、部署Rag、安装Ragan安装、安装Dify安装、安装ollama安装&#xff09; DifyDeepSeek - Excel数据一键可视化&#xff08;创建步骤案例&#xff09;-DSL工程文件&#xff08;可直接导入&#x…

vscode mac版本 配置git

首先使用 type -a git查看git的安装目录 然后在vscode中找到settings配置文件&#xff0c;修改git.path

JVM与性能调优详解

以下是关于 JVM与性能调优 的详细解析&#xff0c;结合理论、实践及常见问题&#xff0c;分多个维度展开&#xff1a; 一、JVM性能调优的核心目标 性能调优的核心目标是通过优化内存管理、垃圾回收&#xff08;GC&#xff09;策略和线程管理&#xff0c;实现以下平衡&#xff…

Vue23Web 基礎性拉滿的面試題(2025版)還沒更新完...

Vue2&3 基礎性1. 關於Vue2和Vue3生命週期的差別2. Vue2&3組件之間傳參不同點Vue2 傳遞與接收Vue3 傳遞與接收 (使用script setup語法糖)Vue3 傳遞與接收 (不使用script setup語法糖) 3. Vue2&3 keep-alive 組件Vue2 keep-aliveVue3 keep-alive 進階性爲什麽POST請求…

基于SpringBoot实现旅游酒店平台功能一

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高&#xff0c;旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求&#xff0c;旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上&#xff0…

【程序自动分析——并查集,离散化】

题目 代码&#xff08;注意不是把p修改为unordered_map&#xff0c;而是增加一个get&#xff09; #include <bits/stdc.h> using namespace std;const int N 2e510; //n个数据&#xff0c;可能引入2*n个离散点int p[N]; bool cannot; unordered_map<int, int> mp…

审批流AntV框架蚂蚁数据可视化X6饼图(附注释)

大家好&#xff0c;这次使用的是AntV的蚂蚁数据可视化X6框架&#xff0c;类似于审批流的场景等&#xff0c;代码如下&#xff1a; X6框架参考网址&#xff1a;https://x6.antv.vision/zh/examples/showcase/practices#bpmn 可以进入该网址&#xff0c;直接复制下方代码进行调试…

linux取代ls的命令行工具:eza

官方仓库 https://github.com/eza-community/eza 安装 cargo install eza验证 eza --version用法 替换ls 别名 安装文档 官方提供的安装文档是这个 https://github.com/eza-community/eza/blob/main/INSTALL.md 可以通过cargo命令安装&#xff0c;debian还可以通过apt安装…

【DeepSeek】Ubuntu快速部署DeepSeek(Ollama方式)

文章目录 人人都该学习的DeepSeekDeepSeek不同版本功能差异DeepSeek与硬件直接的关系DeepSeek系统兼容性部署方式选择部署步骤&#xff08;Ollama方式&#xff09;1.选定适合的deepseek版本2.环境准备3.安装Ollama4.部署deepseek5.测试使用 人人都该学习的DeepSeek DeepSeek 作…

redis热key

在 Redis 中&#xff0c;热 Key&#xff08;Hot Key&#xff09; 是指被频繁访问的 Key&#xff0c;可能会导致以下问题&#xff1a; 性能瓶颈&#xff1a;单个 Redis 实例的 CPU 或网络带宽被耗尽。 数据倾斜&#xff1a;在 Redis 集群中&#xff0c;热 Key 可能导致某个节点…