暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

57.Harmonyos NEXT 图片预览组件实现概览

原创 若城 2025-03-13
186

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

Harmonyos NEXT 图片预览组件实现概览

效果预览

一、组件概述

图片预览组件是一个用于展示和交互图片的高级组件,支持图片的缩放、旋转、滑动切换等功能。该组件由两个核心部分组成:

  1. PicturePreview:外层容器组件,负责图片列表的管理和切换
  2. PicturePreviewImage:内层图片组件,负责单张图片的展示和交互

二、目录结构

├── components/ImagePreview/       # 图片预览组件
│   ├── PicturePreview.ets        # 图片预览外层组件
│   ├── PicturePreviewImage.ets   # 图片预览内层组件
│   ├── ImageItemView.ets         # 图片项视图
│   └── ImageViewerView.ets       # 图片查看器视图
├── model/                        # 数据模型
│   ├── CommonLazyDataSourceModel.ets  # 懒加载数据源模型
│   ├── OffsetModel.ets           # 偏移模型
│   ├── RotateModel.ets           # 旋转模型
│   ├── ScaleModel.ets            # 缩放模型
│   └── PositionModel.ets         # 位置模型
├── utils/                        # 工具类
│   ├── Constrain.ets             # 约束工具
│   ├── FuncUtils.ets             # 功能工具
│   └── Managers.ets              # 管理器
└── constants/                    # 常量
    └── ImageViewerConstants.ets  # 图片查看器常量

三、核心组件实现

1. PicturePreview 组件

PicturePreview 是图片预览的外层容器组件,主要负责:

  • 使用 List 组件实现多图片的移动和展示
  • 通过 ListScroller 控制图片预览的位移
  • 管理图片数据源和懒加载

核心属性

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

核心方法

  • setListOffset:设置列表偏移量
  • setListToIndex:切换到指定索引的图片
  • getListMaxLength:获取图片数量并设置懒加载数据

2. PicturePreviewImage 组件

PicturePreviewImage 是图片预览的内层组件,负责单张图片的展示和交互,主要实现:

  • 使用 matrix4 实现图片的缩放和旋转
  • 使用 offset 实现组件的偏移
  • 提前计算图片属性以便对组件属性进行设置
  • 使用 Image.objectFile 的 Cover 模式使图片能够超出父组件显示

核心属性

// 图片旋转信息 @State imageRotateInfo: RotateModel = new RotateModel(); // 图片缩放信息 @State imageScaleInfo: ScaleModel = new ScaleModel(1.0, 1.0, 1.5, 0.3); // 图片默认大小 -- 是转化后的大小 @State imageDefaultSize: image.Size = { width: 0, height: 0 }; // 本模块提供矩阵变换功能,可对图形进行平移、旋转和缩放等 @State matrix: matrix4.Matrix4Transit = matrix4.identity().copy(); // 图片偏移信息 @State imageOffsetInfo: OffsetModel = new OffsetModel(0, 0);

核心方法

  • calcImageDefaultSize:计算图片的默认尺寸
  • initCurrentImageInfo:初始化图片信息
  • evaluateBound:评估边界以控制图片切换
  • resetCurrentImageInfo:重置图片信息

四、数据模型

1. ScaleModel - 缩放模型

管理图片的缩放状态:

@Observed export class ScaleModel { // 本次缩放因子,用于控制图片的大小显示 public scaleValue: number; // 记录上次缩放完后的缩放因子 public lastValue: number; // 最大放大值 public maxScaleValue: number; // 额外比例值 public extraScaleValue: number; // 默认缩放值 public readonly defaultScaleValue: number = 1; }

2. RotateModel - 旋转模型

管理图片的旋转状态:

@Observed export class RotateModel { // 当前旋转角度 public currentRotate: number; // 最后的角度 public lastRotate: number = 0; // 起步触发旋转的角度 public startAngle: number = 20; }

3. OffsetModel - 偏移模型

管理图片的位移状态:

@Observed export class OffsetModel { // 当前移动偏移量 X public currentX: number; // 当前移动偏移量 Y public currentY: number; // 最后的偏移量 X public lastX: number = 0; // 最后的偏移量 Y public lastY: number = 0; }

4. CommonLazyDataSourceModel - 懒加载数据源模型

实现图片的懒加载,提高性能:

  • 继承自 BasicDataSource,实现 IDataSource 接口
  • 提供数据变化通知机制
  • 支持数据的添加、删除、更新等操作

五、工具类

1. Constrain.ets - 约束工具

提供图片显示的约束功能:

  • ImageFitType:定义图片适配类型(宽度适配、高度适配)
  • getMaxAllowedOffset:计算最大允许的偏移量
  • constrainOffset:约束图片偏移,确保不超出视口边界
  • isToggle:判断是否需要切换图片

2. Managers.ets - 窗口管理器

提供窗口尺寸管理:

class WindowSizeManager { private size: window.Size = { width: 0, height: 0 }; get(): window.Size { return this.size; } }

3. FuncUtils.ets - 功能工具

提供动画和旋转计算功能:

  • runWithAnimation:给函数执行添加动画效果
  • simplestRotationQuarter:计算最简旋转角度,将任意角度转换为0°、90°、180°、270°

六、常量定义

ImageViewerConstants.ets

export class ImageViewerConstants { // 缩放动画的持续时间 static readonly ANIMATE_DURATION: number = 300; // swiper中缓存图片的数量 static readonly SWIPER_CACHE_COUNT: number = 2; // 测试文件名称 static readonly IMAGE_NAME: string = "02.jpg"; }

七、使用示例

@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%') } }

八、实现原理

  1. 图片缩放:使用matrix4矩阵变换实现图片的缩放效果
  2. 图片旋转:通过matrix4矩阵变换实现图片的旋转效果
  3. 图片切换:使用List组件和ListScroller控制图片的切换
  4. 手势处理
    • 单指拖动:移动图片
    • 双指缩放:缩放图片
    • 双指旋转:旋转图片
  5. 边界处理:通过constrainOffset函数约束图片的偏移,确保不超出视口边界
  6. 懒加载:使用CommonLazyDataSourceModel实现图片的懒加载,提高性能

九、总结

图片预览组件是一个功能完善的图片查看器,支持图片的缩放、旋转、滑动切换等功能。通过合理的组件设计和数据模型抽象,实现了高性能、高可用性的图片预览体验。开发者可以通过简单的配置,快速集成该组件到自己的应用中。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论