58.Harmonyos NEXT 图片预览组件架构设计与实现原理

server/2025/3/15 4:36:34/

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

Harmonyos NEXT 图片预览组件架构设计与实现原理

文章目录

  • Harmonyos NEXT 图片预览组件架构设计与实现原理
    • 效果预览
    • 一、组件架构概述
      • 1. 核心组件层次结构
      • 2. 组件职责划分
      • 3. 数据模型设计
    • 二、PicturePreview组件实现
      • 1. 组件定义
      • 2. 核心功能实现
        • 2.1 图片列表管理
        • 2.2 图片切换控制
      • 3. 布局实现
    • 三、技术要点分析
      • 1. 懒加载实现
      • 2. 主轴与交叉轴处理
      • 3. 安全区域适配
    • 四、使用示例
    • 五、总结

效果预览

一、组件架构概述

图片预览组件是一个用于展示和交互图片的高级组件,采用分层设计模式,将复杂功能拆分为多个独立模块,提高代码的可维护性和复用性。组件架构如下:

1. 核心组件层次结构

PicturePreview (外层容器)└── PicturePreviewImage (内层图片组件)└── Image (基础图片渲染)

2. 组件职责划分

组件名称主要职责核心技术
PicturePreview图片列表管理、切换控制List、LazyForEach、ListScroller
PicturePreviewImage单张图片交互、手势处理matrix4、手势识别、偏移计算

3. 数据模型设计

图片预览组件使用多个数据模型来管理不同的状态:

  • ScaleModel: 管理图片缩放状态
  • RotateModel: 管理图片旋转状态
  • OffsetModel: 管理图片位移状态
  • CommonLazyDataSourceModel: 实现图片的懒加载

二、PicturePreview组件实现

1. 组件定义

@Component
export struct PicturePreview {// 滑动方向@Prop listDirection: Axis = Axis.Vertical;// 外部传入的图片数据@Link @Watch('getListMaxLength') imageList: string[];// 背景颜色@State listBGColor: Color = Color.White;// 图片懒加载数据源@State lazyImageList: CommonLazyDataSourceModel<string> = new CommonLazyDataSourceModel();// ...
}

2. 核心功能实现

2.1 图片列表管理
// 获取图片数量和设置懒加载图片数据
getListMaxLength() {this.listMaxLength = this.imageList.length;this.lazyImageList.clearAndPushAll(this.imageList)
}

这段代码实现了图片数据的初始化,将外部传入的图片列表转换为懒加载数据源,提高性能。

2.2 图片切换控制
// 改变到具体页面
setListToIndex = (index: number) => {const WIN_SIZE = windowSizeManager.get();let nIndex = index;if (nIndex < 0) {nIndex = 0} else if (nIndex >= this.listMaxLength) {nIndex = this.listMaxLength - 1}this.listIndex = nIndex;let principalAxisSize = this.listDirection === Axis.Horizontal ? WIN_SIZE.width : WIN_SIZE.heightlet calculatedOffset = Math.abs(nIndex * principalAxisSize) + this.listSpace * nIndex;this.listScroll.scrollTo({yOffset: this.listDirection === Axis.Horizontal ? 0 : calculatedOffset,xOffset: this.listDirection === Axis.Horizontal ? calculatedOffset : 0,animation: {duration: this.listAnimationDuration}})
}

这段代码实现了图片切换功能,通过计算偏移量并使用ListScroller控制滚动位置,实现图片的平滑切换。

3. 布局实现

build() {NavDestination() {List({ scroller: this.listScroll, space: this.listSpace }) {LazyForEach(this.lazyImageList, (imageUrl: string, index: number) => {ListItem() {PicturePreviewImage({imageUrl: imageUrl,listDirection: this.listDirection,setListOffset: this.setListOffset,setListToIndex: this.setListToIndex,imageIndex: index,imageMaxLength: this.listMaxLength,listBGColor: this.listBGColor})}.width("100%")})}.enableScrollInteraction(false) // 禁止List本身的滑动,避免滑动冲突// ...}
}

布局实现使用List组件和LazyForEach实现图片列表的渲染,通过禁用List的滚动交互,将滚动控制权交给PicturePreviewImage组件处理。

三、技术要点分析

1. 懒加载实现

图片预览组件使用CommonLazyDataSourceModel实现懒加载,只加载当前可见的图片,提高性能和内存利用率。

2. 主轴与交叉轴处理

组件支持水平和垂直两种滑动方向,通过listDirection属性控制:

let principalAxisSize = this.listDirection === Axis.Horizontal ? WIN_SIZE.width : WIN_SIZE.height

3. 安全区域适配

.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

通过expandSafeArea属性,确保组件在不同设备上的安全区域适配。

四、使用示例

@Entry
@Component
struct PicturePreviewSample {@State imageList: string[] = [];@State listDirection: Axis = Axis.Horizontal;aboutToAppear(): void {let imageSource:string = $r("app.media.02") as ESObject;this.imageList.push(imageSource,imageSource,imageSource)}build() {RelativeContainer() {PicturePreview({ imageList: this.imageList, listDirection: this.listDirection })}.height('100%').width('100%')}
}

五、总结

图片预览组件通过分层设计和数据模型抽象,实现了高性能、高可用性的图片预览体验。PicturePreview作为外层容器,负责图片列表的管理和切换,而内部的交互细节则由PicturePreviewImage组件处理,形成了清晰的职责划分。

组件的核心技术包括:

  1. 使用List和LazyForEach实现图片列表的高效渲染
  2. 通过ListScroller控制图片的切换
  3. 支持水平和垂直两种滑动方向
  4. 安全区域适配,确保在不同设备上的显示效果

在下一篇教程中,我们将深入探讨PicturePreviewImage组件的实现,了解图片的缩放、旋转和手势处理等功能的实现原理。


http://www.ppmy.cn/server/175060.html

相关文章

ubuntu 在VirtualBox 打不开终端

ctrlaltF3&#xff0c;进入命令行模式sudo nano /etc/default/locale LANG这行的值修改为&#xff1a;en_US.UTF-8执行 locale-gen --purge&#xff0c;等待生成完成reboot重启系统。再次进入系统后&#xff0c;终端就可以正常使用了 参考文章&#xff1a;VirtualBox安装Ubuntu…

蓝桥杯备考:图论初解

1&#xff1a;图的定义 我们学了线性表和树的结构&#xff0c;那什么是图呢&#xff1f; 线性表是一个串一个是一对一的结构 树是一对多的&#xff0c;每个结点可以有多个孩子&#xff0c;但只能有一个父亲 而我们今天学的图&#xff01;就是多对多的结构了 V表示的是图的顶点集…

uni-app中,调用收货地址方法 uni.chooseAddress()不生效的问题

在uni-app中&#xff0c;如果调用收货地址方法 uni.chooseAddress()不生效的话&#xff0c;可以在manifest.json中&#xff0c;打开源码视图&#xff0c;找到mp-weixin&#xff0c;设置 然后将小程序进行重启即可

QT系列教程(13) 事件系统

事件系统 Qt事件系统是非常重要事件传递机制&#xff0c;所有消息传递流程都离不开这个机制&#xff0c;这里主要从重写类的事件响应函数&#xff0c;事件过滤器以及重写event函数三种方式做介绍。 重写事件函数 这种方式最为直接&#xff0c;我们先创建项目,选择QApplicati…

《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(36)太极图化路径 - 不同路径(组合数学优化)

《灵珠觉醒:从零到算法金仙的C++修炼》卷三天劫试炼(36)太极图化路径 - 不同路径(组合数学优化) 哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的太极谷,谷中有一幅巨大的太极图,图中隐藏着无数路径。谷口有一块巨大的石碑,上面刻着一行文字:“欲破…

【webrtc debug tools】 rtc_event_log_to_text

一、rtc_event_log 简介 在学习分析webrtc的过程中&#xff0c;发现其内部提供了一个实时数据捕获接口RtcEventLog。通过该接口可以实时捕获进出webrtc的RTP报文头数据、音视频配置参数、webrtc的探测数据等。其内容实现可参考RtcEventLogImpl类的定义。其文件所在路径 loggin…

ArcGIS水文水资源水环境应用实战:从入门到精通!ArcGIS水文分析及流域特征提取;湖泊水库水环境监测及评价;河道水污染预测与水环境容量计算等

随着水资源日益紧缺和水环境问题日益突出&#xff0c;水文水资源领域面临着前所未有的挑战。ArcGIS 作为强大的地理信息系统平台&#xff0c;凭借其强大的空间分析、数据管理和可视化能力&#xff0c;在水文水资源领域发挥着越来越重要的作用。本文将结合最新技术&#xff0c;探…

TCP网络协议

TCP粘包 1. TCP在接收数据时&#xff0c;多包数据粘在了一起 2. 原因&#xff1a; 1. TCP发送数据时&#xff0c;没有及时发走&#xff0c;会根据缓冲区数据的情况进行重新组包&#xff1b; 2. TCP接收方&#xff0c;没有及时读走缓冲区数据&#xff0c;导致缓冲区大量数…