HarmonyOS应用开发者的宝藏APP-HMOS代码工坊-组件拖拽
@
目录
- 前言
- 准备
- 图片拖拽
- 落位动效
- 拖拽背景
前言
看拖拽效果好久嘞, 今天正好有时间跟着HMOS代码工坊
来实践一下。
准备
需要了解的一些基础
-
默认支持拖出能力的组件(可从组件上拖出数据):Search、TextInput、TextArea、RichEditor、Text、Image、Hyperlink,开发者可通过设置这些组件的draggable属性来控制对默认拖拽能力的使用。
-
默认支持拖入能力的组件(目标组件可响应拖入数据):Search、TextInput、TextArea、RichEditor,开发者可通过设置这些组件的allowDrop属性为null来禁用对默认拖入能力的支持。
-
其他组件需要开发者将draggable属性设置为true,并在onDragStart等接口中实现数据传输相关内容,才能正确处理拖拽能力。
图片拖拽
我们先来做一个图片拖拽到另一个区域做展示的功能,
首先准备一个图片,使用 Image 组件加载
Image($r('app.media.cat')).fitOriginalSize(true)
.draggable(true).onDragEnd((event:DragEvent)=>{
if(event.getResult() == DragResult.DRAG_SUCCESSFUL){
this.showToast("拖拽成功")
}else{
this.showToast("拖拽失败")
}
})
一个用来接收(展示)拖拽图片的组件
Image(this.targetImage)
.fitOriginalSize(true)
.constraintSize({
minWidth:"95%",
minHeight:100
}).backgroundColor(Color.Gray).borderRadius(12)
//设置允许落入的数据类型
.allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
这里的uniformTypeDescriptor
是从@kit.ArkData
导入,还有一些其他需要导入的对象
import { unifiedDataChannel, uniformDataStruct, uniformTypeDescriptor } from '@kit.ArkData';
页面类似这种
当我们长按图片,出现一个放大的动画效果之后,我们就可以拖动图片了。但这时候下面的灰色区域还是不能接收图片。
我们给接收区域加个onDrop
事件,这样当我们将图片拖拽到可以接收图片的区域时,图片右上角会有一个绿色的加号。
但这时候松开手指,目标区域是没有接收到我们拖拽的数据的。我们需要在onDrop
事件中自己处理数据接收
.onDrop((event?:DragEvent)=>{
if(event){
//获取拖拽数据对象
let dragData:UnifiedData = event.getData()
let records: unifiedDataChannel.UnifiedRecord[] = dragData.getRecords();
if(records){
//遍历一下数据
records.forEach((value)=>{
let types = value.getTypes()
if (types.includes(uniformTypeDescriptor.UniformDataType.FILE_URI)) {
const fileUriUds =
value.getEntry(uniformTypeDescriptor.UniformDataType.FILE_URI) as uniformDataStruct.FileUri;
let typeDescriptor = uniformTypeDescriptor.getTypeDescriptor(fileUriUds.fileType);
//拿到的数据是图片类型
if (typeDescriptor.belongsTo(uniformTypeDescriptor.UniformDataType.IMAGE)) {
this.targetImage = fileUriUds.oriUri;
}
}
})
}
}
})
这时候我们就能完成拖拽了。
落位动效
但在松开手指的时候,图片出现的有点生硬,我们可以使用自定义落位动效
,通过动画来消除一下。
rawImageWidth:Length = 0
rawImageHeight:Length = 0
@State targetImageWidth:Length = 0
@State targetImageHeight:Length = 0
先获取图片展示出来之后需要的宽高
.onAreaChange((oldValue,newValue)=>{
this.rawImageWidth = newValue.width
this.rawImageHeight = newValue.height
}
定义一个缩放动画:
customDropAnimation =
() => {
this.getUIContext().animateTo({ duration: 1000, curve: Curve.EaseOut, playMode: PlayMode.Normal }, () => {
this.targetImageWidth = this.rawImageWidth;
this.targetImageHeight = this.rawImageHeight;
})
}
在onDrop
事件中使用
.onDrop((event?:DragEvent)=>{
if(event){
event.useCustomDropAnimation = true;
event.executeDropAnimation(this.customDropAnimation)
}
})
现在我们来看下效果
看起来效果还行。
拖拽背景
有时候我们可能会有自定义拖拽背景的需求,但这里也有一些需要注意的地方:
- 针对默认支持拖拽能力的组件,如果开发者设置了onDragStart,优先执行onDragStart,并根据执行情况决定是否使用系统默认的拖拽能力,具体规则为:
如果开发者返回了自定义预览图,则不再使用系统默认的拖拽预览图;
如果开发者设置了拖拽数据,则不再使用系统默认填充的拖拽数据。
- 文本类组件Text、Search、TextInput、TextArea、RichEditor对选中的文本内容进行拖拽时,不支持自定义预览图。
- 当onDragStart与菜单预览一起使用或使用了默认支持拖拽能力的组件时,预览及菜单项上的自定义内容不支持拖拽。
自定义背景也很简单,我们只需要在onDragStart
事件中返回描述背景的DragItemInfo
对象即可
@Builder
pixelMapBuilder() {
Column() {
Image($r('app.media.startIcon')).fitOriginalSize(true)
}
.backgroundColor($r('sys.color.comp_background_primary'))
.borderRadius(16)
}
.onDragStart(()=>{
let dragItemInfo: DragItemInfo = {
builder: () => {
this.pixelMapBuilder()
},
};
return dragItemInfo;
})
HMOS代码工坊APP已可在华为应用市场下载:
https://appgallery.huawei.com/app/detail?id=com.huawei.hmos.world&channelId=SHARE
【 更多精彩内容,请关注公众号:【名称:HarmonyOS开发者技术,ID:HarmonyOS_Dev】;也欢迎加入鸿蒙开发者交流群:https://work.weixin.qq.com/gm/48f89e7a4c10206e053e01ad124004a0】
更多推荐
所有评论(0)