HarmonyOS NEXT 实现拖动卡片背景模糊效果

server/2025/3/28 16:45:10/

大家好,我是 V 哥。
最近看到在 HarmonyOS NEXT开发中,实现拖动卡片背景模糊的案例效果,在拖动时背景图片模糊,松开后恢复正常。感觉很酷,写一个案例玩一下。

需求分析

首先,咱们来一起分析一下这个效果要怎么实现。

分析需求:卡片可拖动,拖动时背景模糊,松开后恢复。这需要处理拖拽事件和动态调整背景的模糊效果。咱们需要确定如何监听拖拽动作,以及如何动态改变背景的样式。

ArkUI中的组件,比如Stack布局可以用来放置背景和卡片。卡片可能需要使用可拖动的组件,比如PanGesture或者拖拽事件相关的组件。在HarmonyOS中,手势处理通常是通过Gesture组件来实现的,比如PanGesture用于拖动手势。

接下来,背景图片的模糊效果。在ArkUI中,有类似于前端的backdrop-filter样式,或者需要使用某种图像处理模块。

然后,状态管理的问题。当卡片被拖动时,需要触发背景模糊,松开后恢复。这需要维护一个状态变量,比如isDragging,当拖拽开始的时候设置为true,拖拽结束或松开的时候设置为false。这个状态变量控制背景的模糊效果是否应用。

接下来,拖拽的实现。使用PanGesture手势,监听onActionStart、onActionUpdate、onActionEnd事件。在onActionStart时设置isDragging为true,onActionEnd或onActionCancel时设置为false。同时,根据手势的偏移量更新卡片的位置,可能需要使用绝对定位,比如设置卡片的position为绝对定位,然后通过left和top属性来调整位置,或者使用translate属性进行平移。

关于卡片的定位,需要将卡片放在一个容器中,比如Stack布局,这样卡片可以自由移动。然后通过手势事件中的偏移量来更新卡片的位置。需要注意处理手势事件的offsetX和offsetY,或者在onActionUpdate中获取手指移动的差值,然后累加到卡片的位置上。

然后,背景的动态模糊。假设背景是一个Image组件,当isDragging为true时,应用blur效果。例如,在ArkUI中,Image组件可能有effect属性,可以设置为ImageEffect.blur(radius),根据isDragging的状态调整radius的值。或者可能需要使用条件渲染,根据状态改变样式类。

咱们需要创建一个状态变量,比如blurRadius,初始为0,拖动时设置为5,这样背景图片的模糊效果就会动态变化。同时,动画效果可能需要使用动画API,比如animateTo,让模糊过渡更平滑。

另外,需要注意性能问题,频繁的模糊效果可能会影响性能,需要确认HarmonyOS中是否优化了这类效果,或者是否有更好的实现方式,比如使用离屏渲染或者缓存模糊后的图片,不过这可能比较复杂,作为基础功能可能直接动态调整即可。

现在,整合这些思路,代码的大致结构可能是这样的:

• 外层使用Stack布局,包含背景Image和可拖动的卡片。
• 卡片组件包裹在Gesture组件中,监听PanGesture事件。
• 当拖拽开始时,设置isDragging为true,更新背景的模糊效果。
• 拖拽过程中,根据手势的偏移量更新卡片的位置。
• 拖拽结束时,恢复背景的模糊效果。

案例实现

V 哥来总结一下实现步骤:

  1. 创建页面组件,使用Stack布局包含背景和卡片。
  2. 背景图片应用模糊效果,根据isDragging状态变化。
  3. 卡片使用Gesture组件处理PanGesture手势。
  4. 拖动手势事件中更新卡片的位置,并控制isDragging状态。
  5. 状态变化触发背景模糊的样式更新。
  6. 可能需要添加过渡动画使模糊效果更平滑。

在HarmonyOS NEXT中,可以通过以下步骤实现可拖动卡片并控制背景模糊效果:

@Entry
@Component
struct DragCardExample {@State cardPosition: { x: number, y: number } = { x: 0, y: 0 };@State isDragging: boolean = false;private initialPosition: { x: number, y: number } = { x: 0, y: 0 };build() {Stack() {// 背景图片Image($r('app.media.background')).width('100%').height('100%').objectFit(ImageFit.Cover).blur(this.isDragging ? 10 : 0) // 根据拖动状态调整模糊度.animation({ duration: 300, curve: Curve.EaseInOut })// 可拖动卡片Gesture(GesturePriority.Low,PanGesture({onActionStart: () => {this.isDragging = true;this.initialPosition = { ...this.cardPosition };},onActionUpdate: (event: GestureEvent) => {this.cardPosition = {x: this.initialPosition.x + event.offsetX,y: this.initialPosition.y + event.offsetY};},onActionEnd: () => {this.isDragging = false;// 这里可以添加自动回中或其他结束逻辑},onActionCancel: () => {this.isDragging = false;}})) {Column() {Text('拖拽我').fontSize(20).fontColor(Color.Black)}.width(200).height(150).padding(20).backgroundColor(Color.White).borderRadius(16).shadow({ radius: 8, color: '#30000000', offsetX: 2, offsetY: 4 })}.position({ x: this.cardPosition.x, y: this.cardPosition.y }).animation({ duration: 100, curve: Curve.Linear })}.width('100%').height('100%')}
}

实现原理说明:

  1. 状态管理:
    @State cardPosition:记录卡片的当前位置
    @State isDragging:控制拖动状态
    initialPosition:记录拖动前的初始位置

  2. 手势处理:
    • 使用PanGesture实现拖动手势识别
    onActionStart:记录初始位置并设置拖动状态
    onActionUpdate:实时更新卡片位置
    onActionEnd/Cancel:重置拖动状态

  3. 背景模糊控制:
    • 使用blur()API根据isDragging状态动态调整模糊度
    • 添加animation实现平滑的过渡效果

  4. 卡片样式:
    • 使用position实现绝对定位
    • 添加阴影和圆角提升视觉效果
    • 为位置变化添加微小的动画提升拖动手感

扩展建议:

  1. 边界控制: 添加位置限制防止卡片拖出屏幕
   // 在onActionUpdate中添加限制逻辑const maxX = 屏幕宽度 - 卡片宽度;const maxY = 屏幕高度 - 卡片高度;x = Math.min(Math.max(x, 0), maxX);y = Math.min(Math.max(y, 0), maxY);
  1. 磁性吸附效果: 在onActionEnd中添加自动居中逻辑
   animateTo({ duration: 200 }, () => {this.cardPosition = { x: 0, y: 0 };});
  1. 性能优化: 对于复杂背景,建议:
    • 使用缓存后的模糊图片
    • 控制模糊半径不超过15px
    • 在模糊层添加backdropBlur()代替全图模糊

最后

这个实现方案完整展示了如何在HarmonyOS NEXT中结合手势识别、状态管理和视觉效果API,实现具有交互视觉反馈的可拖动卡片效果。关注威哥爱编程,鸿蒙开发一定行。
想要学习鸿蒙开发,一定绕不开学习 ArkTS 语言,V 哥写了三本鸿蒙开发之路的书,第一本《鸿蒙 HarmonyOS NEXT开发之路 卷1 ArkTS 篇》已上市,欢迎鸿蒙开发爱好者读一读,可以帮助你快速系统的拿下 ArkTS,每二本鸿蒙应用开发篇和项目实践篇也即将上市,清华大学出版社正在紧张校稿中。
在这里插入图片描述


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

相关文章

[C++面试] 你了解transform吗?

层级核心知识点入门基本语法、与for_each对比、单/双范围操作进阶动态扩展、原地转换、类型兼容性、异常安全高阶性能优化、C20 Ranges、transform_if模拟 一、入门 1、描述std::transform的基本功能&#xff0c;并写出两种版本的函数原型 std::transform函数是 C 标准库<…

当科技业成为系统性压榨的绞肉机

深夜的硅谷办公室依然灯火通明&#xff0c;键盘敲击声此起彼伏。一位程序员在Slack上收到主管的紧急需求&#xff1a;“这个功能明早必须上线。”他苦笑一声&#xff0c;关掉手机里名为“缓解焦虑”的冥想App——这已是本周第三次被迫服用公司提供的“心灵解药”。此刻&#xf…

CI/CD(五) 安装helm

一、安装 Helm 客户端 方法 1&#xff1a;通过脚本自动安装&#xff08;推荐&#xff09; curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh说明&#xff1a;此脚本会自动下载最新 Helm…

【蓝桥杯速成】| 11.回溯 之 子集问题

题目一&#xff1a;子集 问题描述 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例…

【PCB工艺】基础:电子元器件

电子原理图&#xff08;Schematic Diagram&#xff09;是电路设计的基础&#xff0c;理解电子元器件和集成电路&#xff08;IC&#xff09;的作用&#xff0c;是画好原理图的关键。 本专栏将系统讲解 电子元器件分类、常见 IC、电路设计技巧&#xff0c;帮助你快速掌握电子电路…

Qt开发:QFileDialog的使用

文章目录 QFileDialog的介绍QFileDialog的常用静态方法 QFileDialog的介绍 QFileDialog 是 Qt 框架中提供的一个用于文件选择的标准对话框类&#xff0c;它允许用户在应用程序中选择文件或目录。它是跨平台的&#xff0c;在不同操作系统上会自动适配本地风格的文件对话框。 Q…

Mysql从入门到精通day3————记一次连接查询的武装渗透

一.内连接查询 概念&#xff1a;内连接是最普遍的连接类型&#xff0c;要求构成连接每一部分的每个表都匹配&#xff0c;不匹配的行将被排除 分类&#xff1a;内连接包括相等连接和自然连接&#xff0c;相等连接最为常见&#xff0c;就是使用等号运算符根据每个表共有列的值匹配…

破解云端依赖!如何通过Flowise搭建私有化的端到端AI开发环境

文章目录 前言1. Docker安装Flowise2. Ubuntu安装Cpolar3. 配置Flowise公网地址4. 远程访问Flowise5. 固定Cpolar公网地址6. 固定地址访问 前言 想象一下&#xff0c;当你的同事还在为那些繁琐的工作流程头疼时&#xff0c;你已经用上了超火的 Flowise&#xff0c;轻松搭建复杂…