• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 拖拽控制
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiangtao92-->
5<!--Designer: @piggyguy-->
6<!--Tester: @songyanhong-->
7<!--Adviser: @HelloCrease-->
8
9组件提供了一些属性和接口,可用于配置组件对拖拽事件的响应行为,或影响系统对拖拽事件的处理方式,包括是否允许被拖拽,自定义拖拽预览图的外观等。
10
11> **说明:**
12>
13> 从API version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
14
15ArkUI框架对以下组件实现了默认的拖拽能力,支持对数据的拖出或拖入响应。开发者也可以通过实现通用拖拽事件来自定义拖拽响应。
16
17- 默认支持拖出能力的组件(可从组件上拖出数据):[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[RichEditor](ts-basic-components-richeditor.md)、[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)、[Hyperlink](ts-container-hyperlink.md),开发者可通过设置这些组件的[draggable](ts-universal-attributes-drag-drop.md#draggable)属性来控制对默认拖拽能力的使用。
18
19- 默认支持拖入能力的组件(目标组件可响应拖入数据):[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[RichEditor](ts-basic-components-richeditor.md),开发者可通过设置这些组件的[allowDrop](ts-universal-attributes-drag-drop.md#allowdrop)属性为null来禁用对默认拖入能力的支持。
20
21<!--RP1--><!--RP1End-->其他组件需要开发者将draggable属性设置为true,并在onDragStart等接口中实现数据传输相关内容,才能正确处理拖拽。
22
23> **说明:**
24>
25> Text组件需配合[copyOption](ts-basic-components-text.md#copyoption9)一起使用,设置copyOptions为CopyOptions.InApp或者CopyOptions.LocalDevice26
27## allowDrop
28
29allowDrop(value: Array&lt;UniformDataType&gt; | null): T
30
31设置该组件上允许落入的数据类型。如果未设置allowDrop,组件将默认接受所有数据类型。
32
33**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
34
35**系统能力:** SystemCapability.ArkUI.ArkUI.Full
36
37**参数:**
38
39| 参数名 | 类型                                                         | 必填 | 说明                                            |
40| ------ | ------------------------------------------------------------ | ---- | ----------------------------------------------- |
41| value  | Array\<[UniformDataType](#uniformdatatype)> \| null<sup>12+</sup> | 是   | 设置该组件上允许落入的数据类型。从API version 12开始,允许设置成null使该组件不接受所有的数据类型。|
42
43**返回值:**
44
45| 类型 | 说明 |
46| -------- | -------- |
47| T | 返回当前组件。 |
48
49## draggable
50
51draggable(value: boolean): T
52
53设置该组件是否允许拖拽。默认情况下,组件不允许拖拽。
54
55**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
56
57**系统能力:** SystemCapability.ArkUI.ArkUI.Full
58
59**参数:**
60
61| 参数名 | 类型    | 必填 | 说明                                           |
62| ------ | ------- | ---- | ---------------------------------------------- |
63| value  | boolean | 是   | 设置该组件是否允许进行拖拽。true表示允许拖拽,false表示不允许拖拽。|
64
65**返回值:**
66
67| 类型 | 说明 |
68| -------- | -------- |
69| T | 返回当前组件。 |
70
71## dragPreview<sup>11+</sup>
72
73dragPreview(value: CustomBuilder | DragItemInfo | string): T
74
75设置组件浮起和拖拽过程中的预览图。
76
77**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
78
79**系统能力:** SystemCapability.ArkUI.ArkUI.Full
80
81**参数:**
82
83| 参数名 | 类型                                                         | 必填 | 说明                                                         |
84| ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
85| value  | [CustomBuilder](ts-types.md#custombuilder8)&nbsp;\|&nbsp;[DragItemInfo](ts-universal-events-drag-drop.md#dragiteminfo) \| string<sup>12+</sup> | 是   | 设置组件浮起和拖拽过程中的预览图,仅在[onDragStart](ts-universal-events-drag-drop.md#ondragstart)拖拽方式中有效。<br/>当组件支持拖拽并同时设置[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu8)的预览图时,则长按浮起的预览图以[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu8)设置的预览图为准。开发者在[onDragStart](ts-universal-events-drag-drop.md#ondragstart)中返回的背板图优先级低于[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)设置的预览图,当设置了[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)预览图时,拖拽过程中的背板图使用[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)预览图。由于[CustomBuilder](ts-types.md#custombuilder8)需要离线渲染之后才能使用,因此存在一定的性能开销和时延,推荐优先使用 [DragItemInfo](ts-universal-events-drag-drop.md#dragiteminfo)中的[PixelMap](../../apis-image-kit/arkts-apis-image-PixelMap.md)方式。<br/> 当传入类型为string的id时,则将id对应组件的截图作为预览图。如果id对应的组件无法查找到,或者id对应的组件[Visibility](ts-appendix-enums.md#visibility)属性设置成None/Hidden,则对组件自身进行截图作为拖拽预览图。目前截图不含有亮度、阴影、模糊和旋转等视觉效果。|
86
87**返回值:**
88
89| 类型 | 说明 |
90| -------- | -------- |
91| T | 返回当前组件。 |
92
93## dragPreview<sup>15+</sup>
94
95dragPreview(preview: CustomBuilder | DragItemInfo | string, config?: PreviewConfiguration):T
96
97自定义组件拖拽过程中的预览图,仅用于设置浮起效果或者禁用浮起效果。
98
99**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。
100
101**系统能力:** SystemCapability.ArkUI.ArkUI.Full
102
103**参数:**
104
105| 参数名 | 类型                                                         | 必填 | 说明                                                         |
106| ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
107| preview  | [CustomBuilder](ts-types.md#custombuilder8)&nbsp;\|&nbsp;[DragItemInfo](ts-universal-events-drag-drop.md#dragiteminfo) \| string | 是   | 设置组件浮起和拖拽过程中的预览图,仅在[onDragStart](ts-universal-events-drag-drop.md#ondragstart)拖拽方式中有效。<br/>当组件支持拖拽并同时设置[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu8)的预览图时,则长按浮起的预览图以[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu8)设置的预览图为准。开发者在[onDragStart](ts-universal-events-drag-drop.md#ondragstart)中返回的背板图优先级低于[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)设置的预览图,当设置了[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)预览图时,拖拽过程中的背板图使用[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)预览图。由于[CustomBuilder](ts-types.md#custombuilder8)需要离线渲染之后才能使用,因此存在一定的性能开销和时延,推荐优先使用 [DragItemInfo](ts-universal-events-drag-drop.md#dragiteminfo)中的[PixelMap](../../apis-image-kit/arkts-apis-image-PixelMap.md)方式。<br/> 当传入类型为string的id时,则将id对应组件的截图作为预览图。如果id对应的组件无法查找到,或者id对应的组件[Visibility](ts-appendix-enums.md#visibility)属性设置成None/Hidden,则对组件自身进行截图作为拖拽预览图。目前截图不含有亮度、阴影、模糊和旋转等视觉效果。|
108| config | [PreviewConfiguration](ts-universal-events-drag-drop.md#previewconfiguration15) | 否 | 对自定义拖拽过程中的预览图进行配置。<br/>只对[dragPreview](#dragpreview11)中的预览生效。|
109
110**返回值:**
111
112| 类型 | 说明 |
113| -------- | -------- |
114| T | 返回当前组件。 |
115
116## dragPreviewOptions<sup>11+</sup>
117
118dragPreviewOptions(value: DragPreviewOptions, options?: DragInteractionOptions): T
119
120设置拖拽过程中预览图处理模式,数量角标的显示以及预览图浮起的交互模式。不支持onItemDragStart拖拽方式。
121
122**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
123
124**系统能力:** SystemCapability.ArkUI.ArkUI.Full
125
126**参数:**
127
128| 参数名 | 类型                                                            | 必填 | 说明                                                         |
129| ------ | -------------------------------------------------------------- | ---- | ------------------------------------------------------------ |
130| value  | [DragPreviewOptions](#dragpreviewoptions11)<sup>11+</sup>      | 是   | 设置拖拽过程中预览图处理模式及数量角标的显示。|
131| options<sup>12+</sup>| [DragInteractionOptions](#draginteractionoptions12)<sup>12+</sup>| 否   | 设置拖拽过程中预览图浮起的交互模式。<br/>默认值:空|
132
133**返回值:**
134
135| 类型 | 说明 |
136| -------- | -------- |
137| T | 返回当前组件。 |
138
139## DragPreviewOptions<sup>11+</sup>
140
141**系统能力:** SystemCapability.ArkUI.ArkUI.Full
142
143| 名称 | 类型 | 只读 | 可选 | 说明 |
144| -------- | -------- | -------- | -------- | --- |
145| mode | [DragPreviewMode](#dragpreviewmode11枚举说明) &nbsp;\|&nbsp; Array<[DragPreviewMode](#dragpreviewmode11枚举说明)><sup>12+</sup> | 否 | 是 | 表示拖拽过程中背板图处理模式。<br/>默认值:DragPreviewMode.AUTO<br/>当组件同时设置DragPreviewMode.AUTO和其它枚举值时,以DragPreviewMode.AUTO为准,其它枚举值设置无效。<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
146| numberBadge<sup>12+</sup> | boolean &nbsp;\|&nbsp; number | 否 | 是 | 控制数量角标是否显示,或强制设置显示的数量。当设置数量角标时取值范围为[0,2<sup>31</sup>-1],超过取值范围时会按默认状态处理。当设置为浮点数时,只显示整数部分。<br/>**说明:** <br>在多选拖拽场景,需通过该接口设置拖拽对象的数量。<br/>默认值:true。<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
147| modifier<sup>12+</sup> | [ImageModifier](#imagemodifier12)| 否 | 是 | 用于配置拖拽背板图的样式Modifier对象,可使用图片组件所支持的属性和样式来配置背板图样式(参考示例6),当前支持透明度,阴影,背景模糊度,圆角。文本拖拽只支持默认效果,不支持通过modifier进行自定义。<br/>1.透明度<br/>通过[opacity](ts-universal-attributes-opacity.md#opacity)设置不透明度,不透明度的取值范围为0-1。设置0或不设置时采用默认值0.95,设置1或异常值时不透明。<br/>2.阴影<br/>通过[shadow](ts-universal-attributes-image-effect.md#shadow)设置阴影。<br/>3.背景模糊度<br/>通过[backgroundEffect](ts-universal-attributes-background.md#backgroundeffect11)或[backgroundBlurStyle](ts-universal-attributes-background.md#backgroundblurstyle9)设置背景模糊度,如果两者同时设置,以后设置的属性为准。<br/>4.圆角<br/>通过[border](ts-universal-attributes-border.md#border)或[borderRadius](ts-universal-attributes-border.md#borderradius)设置圆角,当同时在mode和modifier中设置圆角,mode设置的圆角显示优先级低于modifier设置。<br/>默认值:空,无法修改属性。<br>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
148| sizeChangeEffect<sup>19+</sup> | [DraggingSizeChangeEffect](#draggingsizechangeeffect19枚举说明)<sup>19+</sup> | 否 | 是 | 用于选择长按浮起图与拖拽预览图过渡效果。<br/>默认值:DraggingSizeChangeEffect.DEFAULT。<br>**原子化服务API:** 从API version 19开始,该接口支持在原子化服务中使用。|
149
150## DragPreviewMode<sup>11+</sup>枚举说明
151
152**系统能力:** SystemCapability.ArkUI.ArkUI.Full
153
154| 名称 | 值 | 说明 |
155| -------- | ------- | -------- |
156| AUTO  | 1 | 系统根据拖拽场景自动改变跟手点位置,根据规则自动对拖拽背板图进行缩放变换等。<br>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
157| DISABLE_SCALE  | 2 | 禁用系统对拖拽背板图的缩放行为。<br>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
158| ENABLE_DEFAULT_SHADOW<sup>12+</sup> | 3 | 启用非文本类组件默认阴影效果。<br>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
159| ENABLE_DEFAULT_RADIUS<sup>12+</sup> | 4 | 启用非文本类组件统一圆角效果,默认值12vp。当应用自身设置的圆角值大于默认值或modifier设置的圆角时,则显示应用自定义圆角效果。<br>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
160| ENABLE_DRAG_ITEM_GRAY_EFFECT<sup>18+</sup> | 5 | 启用支持原拖拽对象灰显(透明度)效果,对文本内容拖拽不生效。用户拖起时原对象显示灰显效果,释放时原对象恢复原有效果。开启默认灰显效果后,不建议在拖拽开始后自行修改透明度,如果开发者在拖拽发起后自行修改应用透明度,则灰显效果将被覆盖,且在结束拖拽时无法正确恢复原始透明度效果。<br>**原子化服务API**:从API version 18开始,该接口支持在原子化服务中使用。 |
161| ENABLE_MULTI_TILE_EFFECT<sup>18+</sup> | 6 | 启用支持多选对象鼠标拖拽不聚拢效果,各拖拽图显示在其原始位置的相对位置,当满足多选的情况下且isMultiSelectionEnabled为true时该参数才生效。不聚拢效果优先级高于[dragPreview](#dragpreview11)。不支持二次拖拽、圆角和缩放设置。<br>**原子化服务API**:从API version 18开始,该接口支持在原子化服务中使用。 |
162| ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW<sup>19+</sup> | 7 | 启用支持以拖拽预览图初始尺寸计算跟手点位置,长按浮起图和拖拽图不一致时使用。鼠标拖拽,设置DragPreviewMode.ENABLE_MULTI_TILE_EFFECT时不生效。<br>**原子化服务API**:从API version 19开始,该接口支持在原子化服务中使用。 |
163
164## DraggingSizeChangeEffect<sup>19+</sup>枚举说明
165
166当一个节点上同时设置长按浮起预览(参考[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu12))与拖拽时,使用该字段设置长按浮起预览图与拖拽预览图过渡动效方式。
167
168**原子化服务API:** 从API version 19开始,该接口支持在原子化服务中使用。
169
170**系统能力:** SystemCapability.ArkUI.ArkUI.Full
171
172| 名称 | 值 | 说明 |
173| -------- | ------- | -------- |
174| DEFAULT | 0 | 发起拖拽时直接从菜单预览图切换为最终尺寸的拖拽预览图。 |
175| SIZE_TRANSITION | 1 | 发起拖拽时,由菜单预览图直接切换为拖拽预览图,尺寸逐步从菜单预览图尺寸过渡到最终预览图尺寸,设置了[DragPreviewMode](#dragpreviewmode11枚举说明)中的DISABLE_SCALE枚举值时尺寸过渡不生效。这在长按浮起预览图与拖拽预览图相同时使用。 |
176| SIZE_CONTENT_TRANSITION | 2 | 发起拖拽时,由菜单预览图逐步过渡切换为最终拖拽预览图,设置[DragPreviewMode](#dragpreviewmode11枚举说明)中的DISABLE_SCALE时尺寸过渡不生效。这常用于菜单预览图与拖拽预览图差异较大时使用,过渡效果包含内容透明度及尺寸变化。 |
177
178
179## DragInteractionOptions<sup>12+</sup>
180
181**系统能力:** SystemCapability.ArkUI.ArkUI.Full
182
183| 名称 | 类型 | 只读 | 可选 | 说明 |
184| -------- | -------- | -------- | -------- | ---- |
185| isMultiSelectionEnabled | boolean | 否 | 是 | 表示拖拽过程中背板图是否支持多选聚拢效果。true表示支持多选聚拢效果,false表示不支持多选聚拢效果。该参数只在[Grid](ts-container-grid.md)和[List](ts-container-list.md)组件中的[GridItem](ts-container-griditem.md)组件和[ListItem](ts-container-listitem.md)组件生效。<br/>当一个item组件设置为多选拖拽时,该组件的子组件不可拖拽。聚拢组件预览图设置的优先级为[dragPreview](#dragpreview11)中的string,dragPreview中的PixelMap,组件自截图,不支持dragPreview中的Builder形式。<br/>不支持组件绑定[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu12)中参数存在isShown的模式。<br/>默认值:false<br/>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
186| defaultAnimationBeforeLifting | boolean | 否 | 是 | 表示是否启用长按浮起阶段组件自身的默认点按效果(缩小)。true表示启用默认点按效果,false表示不启用默认点按效果。<br/>默认值:false <br/>**原子化服务API**:从API version 12开始,该接口支持在原子化服务中使用。 |
187| isLiftingDisabled<sup>15+</sup> | boolean | 否 | 是 | 表示长按拖拽时,是否禁用浮起效果。true表示禁用浮起效果,false表示不禁用浮起效果。<br/>如果设置为true,当组件支持拖拽并同时设置[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu8)时,仅弹出配置的自定义菜单预览。 <br/>默认值:false<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 |
188| enableEdgeAutoScroll<sup>18+</sup> | boolean | 否 | 是 | 设置在拖拽至可滚动组件边缘时是否触发自动滚屏。true表示触发自动滚屏,false表示不触发自动滚屏。<br />默认值:true<br/>**原子化服务API**:从API version 18开始,该接口支持在原子化服务中使用。 |
189| enableHapticFeedback<sup>18+</sup> | boolean | 否 | 是 | 表示拖拽时是否启用震动。true表示启用震动,false表示不启用震动。仅在存在蒙层的预览(通过[bindContextMenu](ts-universal-attributes-menu.md#bindcontextmenu12))场景生效。<br/>**注意:** 仅当应用具备 ohos.permission.VIBRATE 权限,且用户启用了触感反馈时才会生效。<br/>默认值:false<br/>**原子化服务API**:从API version 18开始,该接口支持在原子化服务中使用。 |
190
191## UniformDataType
192
193type UniformDataType = UniformDataType
194
195标准化数据类型。
196
197**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
198
199**系统能力:** SystemCapability.ArkUI.ArkUI.Full
200
201| 类型 | 说明 |
202| ----- | ----------------- |
203| [UniformDataType](../../apis-arkdata/js-apis-data-uniformTypeDescriptor.md#uniformdatatype) | 标准化数据类型。|
204
205## ImageModifier<sup>12+</sup>
206
207type ImageModifier = ImageModifier
208
209图片组件modifier对象。
210
211**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
212
213**系统能力:** SystemCapability.ArkUI.ArkUI.Full
214
215| 类型 | 说明 |
216| ----- | ----------------- |
217| [ImageModifier](ts-universal-attributes-attribute-modifier.md) | 图片组件modifier对象。|
218
219## 示例
220### 示例1(允许拖拽和落入)
221
222示例1通过配置allowDrop设置组件是否可落入,通过配置draggable设置组件是否可拖拽。
223
224```ts
225// xxx.ets
226import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
227
228@Entry
229@Component
230struct ImageExample {
231  @State uri: string = "";
232  @State aBlockArr: string[] = [];
233  @State bBlockArr: string[] = [];
234  @State AVisible: Visibility = Visibility.Visible;
235  @State dragSuccess :Boolean = false;
236
237  build() {
238    Column() {
239      Text('Image拖拽')
240        .fontSize('30dp')
241      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
242        Image($r('app.media.icon'))
243          .width(100)
244          .height(100)
245          .border({ width: 1 })
246          .visibility(this.AVisible)
247          .draggable(true)
248          .onDragEnd((event: DragEvent) => {
249            let ret = event.getResult();
250            if(ret == 0) {
251              console.info("enter ret == 0")
252              this.AVisible = Visibility.Hidden;
253            } else {
254              console.info("enter ret != 0")
255              this.AVisible = Visibility.Visible;
256            }
257          })
258      }
259      .margin({ bottom: 20 })
260      Row() {
261        Column(){
262          Text('不允许释放区域')
263            .fontSize('15dp')
264            .height('10%')
265          List(){
266            ForEach(this.aBlockArr, (item:string, index) => {
267              ListItem() {
268                Image(item)
269                  .width(100)
270                  .height(100)
271                  .border({width: 1})
272              }
273              .margin({ left: 30 , top : 30})
274            }, (item:string) => item)
275          }
276          .height('90%')
277          .width('100%')
278          .allowDrop([uniformTypeDescriptor.UniformDataType.TEXT])
279          .onDrop((event?: DragEvent, extraParams?: string) => {
280            this.uri = JSON.parse(extraParams as string)?.extraInfo;
281            this.aBlockArr.splice(JSON.parse(extraParams as string)?.insertIndex, 0, this.uri);
282            console.info("ondrop not udmf data");
283          })
284          .border({width: 1})
285        }
286        .height("50%")
287        .width("45%")
288        .border({ width: 1 })
289        .margin({ left: 12 })
290        Column(){
291          Text('可释放区域')
292            .fontSize('15dp')
293            .height('10%')
294          List(){
295            ForEach(this.bBlockArr, (item:string, index) => {
296              ListItem() {
297                Image(item)
298                  .width(100)
299                  .height(100)
300                  .border({width: 1})
301              }
302              .margin({ left: 30 , top : 30})
303            }, (item:string) => item)
304          }
305          .border({width: 1})
306          .height('90%')
307          .width('100%')
308          .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
309          .onDrop((event?: DragEvent, extraParams?: string) => {
310            console.info("enter onDrop")
311            let dragData:UnifiedData = (event as DragEvent).getData() as UnifiedData;
312            if(dragData != undefined) {
313              let arr:Array<unifiedDataChannel.UnifiedRecord> = dragData.getRecords();
314              if(arr.length > 0) {
315                let image = arr[0] as unifiedDataChannel.Image;
316                this.uri = image.imageUri;
317                this.bBlockArr.splice(JSON.parse(extraParams as string)?.insertIndex, 0, this.uri);
318              } else {
319                console.info(`dragData arr is null`)
320              }
321            } else {
322              console.info(`dragData  is undefined`)
323            }
324            console.info("ondrop udmf data");
325            this.dragSuccess = true
326          })
327        }
328        .height("50%")
329        .width("45%")
330        .border({ width: 1 })
331        .margin({ left: 12 })
332      }
333    }.width('100%')
334  }
335}
336```
337
338![dragImage.gif](figures/dragImage.gif)
339
340### 示例2(设置预览图)
341
342示例2通过配置dragPreview设置拖拽过程的预览图。
343
344```ts
345// xxx.ets
346@Entry
347@Component
348struct DragPreviewDemo{
349  @Builder dragPreviewBuilder() {
350    Column() {
351      Text("dragPreview")
352        .width(150)
353        .height(50)
354        .fontSize(20)
355        .borderRadius(10)
356        .textAlign(TextAlign.Center)
357        .fontColor(Color.Black)
358        .backgroundColor(Color.Pink)
359    }
360  }
361
362  @Builder MenuBuilder() {
363    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
364      Text("menu item 1")
365        .fontSize(15)
366        .width(100)
367        .height(40)
368        .textAlign(TextAlign.Center)
369        .fontColor(Color.Black)
370        .backgroundColor(Color.Pink)
371      Divider()
372        .height(5)
373      Text("menu item 2")
374        .fontSize(15)
375        .width(100)
376        .height(40)
377        .textAlign(TextAlign.Center)
378        .fontColor(Color.Black)
379        .backgroundColor(Color.Pink)
380    }
381    .width(100)
382  }
383
384  build() {
385    Row() {
386      Column() {
387        Image('/resource/image.jpeg')
388          .width("30%")
389          .draggable(true)
390          .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
391          .onDragStart(() => {
392            console.info("Image onDragStart")
393          })
394          .dragPreview(this.dragPreviewBuilder)
395      }
396      .width("100%")
397    }
398    .height("100%")
399  }
400}
401```
402
403![dragPreview.gif](figures/dragPreview.gif)
404
405### 示例3(设置背板图样式)
406
407示例3通过配置dragPreviewOptions为ENABLE_DEFAULT_SHADOW、ENABLE_DEFAULT_RADIUS和ENABLE_DRAG_ITEM_GRAY_EFFECT设置默认阴影、统一圆角效果与灰显效果。
408
409```ts
410// xxx.ets
411@Entry
412@Component
413struct dragPreviewOptionsDemo{
414  build() {
415    Row() {
416      Column() {
417        Image('/resource/image.jpeg')
418          .margin({ top: 10 })
419          .width("30%")
420          .draggable(true)
421          .dragPreviewOptions({ mode: DragPreviewMode.AUTO })
422        Image('/resource/image.jpeg')
423          .margin({ top: 10 })
424          .width("30%")
425          .border({ radius: { topLeft: 1, topRight: 2, bottomLeft: 4, bottomRight: 8 } })
426          .draggable(true)
427          .onDragStart(() => {
428            console.info("Image onDragStart")
429          })
430          .dragPreviewOptions({ mode: [ DragPreviewMode.ENABLE_DEFAULT_SHADOW, DragPreviewMode.ENABLE_DEFAULT_RADIUS, DragPreviewMode.ENABLE_DRAG_ITEM_GRAY_EFFECT ] })
431      }
432      .width("100%")
433      .height("100%")
434    }
435  }
436}
437```
438
439![dragPreviewMode.gif](figures/dragPreviewMode.gif)
440
441
442### 示例4(设置多选拖拽)
443
444示例4通过配置isMultiSelectionEnabled实现Grid组件的多选拖拽效果。
445
446```ts
447@Entry
448@Component
449struct Example {
450  @State numbers: number[] = [0, 1, 2, 3, 4 , 5, 6, 7, 8]
451  build() {
452    Column({ space: 5}) {
453      Grid() {
454        ForEach(this.numbers, (item: number) => {
455          GridItem() {
456            Column()
457              .backgroundColor(Color.Blue)
458              .width('100%')
459              .height('100%')
460          }
461          .width(90)
462          .height(90)
463          .selectable(true)
464          .selected(true)
465          .dragPreviewOptions({}, {isMultiSelectionEnabled:true})
466          .onDragStart(()=>{
467
468          })
469    }, (item: string) => item)
470      }
471      .columnsTemplate('1fr 1fr 1fr')
472      .rowsTemplate('1fr 1fr 1fr')
473      .height(300)
474    }
475    .width('100%')
476  }
477}
478```
479
480![isMultiSelectionEnabled.gif](figures/isMultiSelectionEnabled.gif)
481
482### 示例5(设置默认点按效果)
483
484示例5通过配置defaultAnimationBeforeLifting实现Grid组件的默认点按效果。
485
486```ts
487@Entry
488@Component
489struct Example {
490  @State numbers: number[] = [0, 1, 2, 3, 4 , 5, 6, 7, 8]
491  build() {
492    Column({ space: 5}) {
493      Grid() {
494        ForEach(this.numbers, (item: number) => {
495          GridItem() {
496            Column()
497              .backgroundColor(Color.Blue)
498              .width('100%')
499              .height('100%')
500          }
501          .width(90)
502          .height(90)
503          .selectable(true)
504          .selected(true)
505          .dragPreviewOptions({}, {isMultiSelectionEnabled:true, defaultAnimationBeforeLifting:true})
506          .onDragStart(()=>{
507
508          })
509    }, (item: string) => item)
510      }
511      .columnsTemplate('1fr 1fr 1fr')
512      .rowsTemplate('1fr 1fr 1fr')
513      .height(300)
514    }
515    .width('100%')
516  }
517}
518```
519
520![defaultAnimationBeforeLifting.gif](figures/defaultAnimationBeforeLifting.gif)
521
522### 示例6(自定义背板图样式)
523
524示例6通过配置ImageModifier实现Image组件的自定义背板图样式。
525
526```ts
527// xxx.ets
528import { ImageModifier } from '@kit.ArkUI';
529
530@Entry
531@Component
532struct dragPreviewOptionsDemo{
533  @State myModifier: ImageAttribute = new ImageModifier().opacity(0.5)
534  @State vis: boolean = true
535  @State changeValue: string = ''
536  @State submitValue: string = ''
537  @State positionInfo: CaretOffset = { index: 0, x: 0, y: 0 }
538  controller: SearchController = new SearchController()
539  @State OpacityIndex: number = 0
540  @State OpacityList:(number | undefined | null)[]=[
541    0.3,0.5,0.7,1,-50,0,10,undefined,null
542  ]
543  build() {
544    Row() {
545      Column() {
546        Text(this.OpacityList[this.OpacityIndex] + "")
547        Button("Opacity")
548          .onClick(()=> {
549            this.OpacityIndex++
550            if(this.OpacityIndex > this.OpacityList.length - 1){
551              this.OpacityIndex = 0
552            }
553          })
554        Image($r('app.media.image'))
555          .margin({ top: 10 })
556          .width("100%")
557          .draggable(true)
558          .dragPreviewOptions({modifier: this.myModifier.opacity(this.OpacityList[this.OpacityIndex]) as ImageModifier})
559      }
560      .width("50%")
561      .height("50%")
562    }
563  }
564}
565```
566
567![imageModifier.gif](figures/imageModifier.gif)
568
569### 示例7(图片拖拽设置)
570
571示例7展示了不同图片(在线图片资源、本地图片资源和PixelMap)在拖拽时组件的设置。
572使用网络图片时,需要申请权限ohos.permission.INTERNET。具体申请方式请参考[声明权限](../../../security/AccessToken/declare-permissions.md)。
573
574```ts
575// xxx.ets
576import { uniformTypeDescriptor, unifiedDataChannel } from '@kit.ArkData';
577import { image } from '@kit.ImageKit';
578import { request } from '@kit.BasicServicesKit';
579import { fileIo } from '@kit.CoreFileKit';
580import { buffer } from '@kit.ArkTS';
581import { BusinessError } from '@kit.BasicServicesKit';
582
583@Entry
584@Component
585struct ImageDrag {
586  @State targetImage1: string | PixelMap | null = null;
587  @State targetImage2: string | PixelMap | null = null;
588  @State targetImage3: string | PixelMap | null = null;
589  context: Context | undefined = this.getUIContext().getHostContext();
590  filesDir = this.context?.filesDir;
591
592  public async createPixelMap(pixelMap: unifiedDataChannel.SystemDefinedPixelMap): Promise<image.PixelMap | null> {
593    let mWidth: number = (pixelMap.details?.width ?? -1) as number;
594    let mHeight: number = (pixelMap.details?.height ?? -1) as number;
595    let mPixelFormat: image.PixelMapFormat =
596      (pixelMap.details?.['pixel-format'] ?? image.PixelMapFormat.UNKNOWN) as image.PixelMapFormat;
597    let mItemPixelMapData: Uint8Array = pixelMap.rawData;
598    const opts: image.InitializationOptions = {
599      editable: false, pixelFormat: mPixelFormat, size: {
600        height: mHeight,
601        width: mWidth
602      }
603    };
604    const buffer: ArrayBuffer = mItemPixelMapData.buffer.slice(mItemPixelMapData.byteOffset,
605      mItemPixelMapData.byteLength + mItemPixelMapData.byteOffset);
606    try {
607      let pixelMap: image.PixelMap = await image.createPixelMap(buffer, opts);
608      return pixelMap;
609    } catch (err) {
610      console.error('dragtest--> getPixelMap', err);
611      return null;
612    }
613  }
614
615  build() {
616    Column() {
617      Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center }) {
618        // 在线图片资源拖出
619        Column() {
620          Text('Online Image').fontSize(14)
621          Image('https://www.example.com/xxx.png')// 请填写一个具体的网络图片地址
622            .objectFit(ImageFit.Contain)
623            .draggable(true)
624            .onDragStart(() => {
625            })
626            .width(100)
627            .height(100)
628        }
629        .border({
630          width: 2,
631          color: Color.Gray,
632          radius: 5,
633          style: BorderStyle.Dotted
634        })
635        .alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center)
636
637        // 本地图片资源拖出
638        Column() {
639          Text('Local Image').fontSize(14)
640          Image($r('app.media.example'))
641            .objectFit(ImageFit.Contain)
642            .draggable(true)
643            .onDragStart(() => {
644            })
645            .width(100)
646            .height(100)
647        }
648        .border({
649          width: 2,
650          color: Color.Gray,
651          radius: 5,
652          style: BorderStyle.Dotted
653        })
654        .alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center)
655
656        // PixelMap拖出
657        Column() {
658          Text('PixelMap').fontSize(14)
659          Image(this.context?.resourceManager.getDrawableDescriptor($r('app.media.example').id).getPixelMap())
660            .objectFit(ImageFit.Contain)
661            .draggable(true)
662            .onDragStart(() => {
663            })
664            .width(100)
665            .height(100)
666        }
667        .border({
668          width: 2,
669          color: Color.Gray,
670          radius: 5,
671          style: BorderStyle.Dotted
672        })
673        .alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center)
674      }
675
676      // 落入数据类型为Image
677      Text('Data type is Image').fontSize(14).margin({ top: 10 })
678      Column() {
679        Image(this.targetImage1)
680          .objectFit(ImageFit.Contain)
681          .width('70%')
682          .height('70%')
683          .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
684          .onDrop((event: DragEvent, extraParams: string) => {
685            if (extraParams === null || extraParams === undefined) {
686              return;
687            }
688            // 通过extraParams获取图片
689            let arr: Record<string, object> = JSON.parse(extraParams) as Record<string, object>;
690            let uri = arr['extraInfo'];
691            if (typeof uri == 'string') {
692              this.targetImage1 = uri;
693              try {
694                request.downloadFile(this.context, {
695                  url: uri,
696                  filePath: this.filesDir + '/example.png'
697                }).then((downloadTask: request.DownloadTask) => {
698                  let file = fileIo.openSync(this.filesDir + '/example.png', fileIo.OpenMode.READ_WRITE);
699                  let arrayBuffer = new ArrayBuffer(1024);
700                  let readLen = fileIo.readSync(file.fd, arrayBuffer);
701                  let buf = buffer.from(arrayBuffer, 0, readLen);
702                  console.info(`The content of file: ${buf.toString()}`);
703                  fileIo.closeSync(file);
704                })
705              } catch (error) {
706              }
707            }
708          })
709      }
710      .width('70%')
711      .height('25%')
712      .border({
713        width: 2,
714        color: Color.Gray,
715        radius: 5,
716        style: BorderStyle.Dotted
717      })
718      .alignItems(HorizontalAlign.Center)
719      .justifyContent(FlexAlign.Center)
720
721      Column() {
722        Image(this.targetImage2)
723          .objectFit(ImageFit.Contain)
724          .width('70%')
725          .height('70%')
726          .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
727          .onDrop((event: DragEvent, extraParams: string) => {
728            // 通过uniformTypeDescriptor获取图片
729            let data: UnifiedData = event.getData();
730            let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords();
731            if (records[0].getType() === uniformTypeDescriptor.UniformDataType.IMAGE) {
732              let image: unifiedDataChannel.Image = records[0] as unifiedDataChannel.Image;
733              this.targetImage2 = image.imageUri;
734            }
735          })
736      }
737      .width('70%')
738      .height('25%')
739      .border({
740        width: 2,
741        color: Color.Gray,
742        radius: 5,
743        style: BorderStyle.Dotted
744      })
745      .alignItems(HorizontalAlign.Center)
746      .justifyContent(FlexAlign.Center)
747
748      // 落入数据类型为PixelMap
749      Text('Data type is PixelMap').fontSize(14).margin({ top: 10 })
750      Column() {
751        Image(this.targetImage3)
752          .objectFit(ImageFit.Contain)
753          .width('70%')
754          .height('70%')
755          .allowDrop([uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP])
756          .onDrop(async (event: DragEvent, extraParams: string) => {
757            // 通过uniformTypeDescriptor获取图片
758            let data: UnifiedData = event.getData();
759            let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords();
760            if (records[0].getType() === uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP) {
761              let record: unifiedDataChannel.SystemDefinedPixelMap =
762                records[0] as unifiedDataChannel.SystemDefinedPixelMap;
763              this.targetImage3 = await this.createPixelMap(record);
764
765              // 落盘到本地
766              const imagePackerApi = image.createImagePacker();
767              let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
768              const path: string = this.context?.cacheDir + "/pixel_map.jpg";
769              let file = fileIo.openSync(path, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE);
770              imagePackerApi.packToFile(this.targetImage3, file.fd, packOpts).then(() => {
771                // 直接打包进文件
772              }).catch((error: BusinessError) => {
773                console.error('Failed to pack the image. And the error is: ' + error);
774              })
775            }
776          })
777      }
778      .width('70%')
779      .height('25%')
780      .border({
781        width: 2,
782        color: Color.Gray,
783        radius: 5,
784        style: BorderStyle.Dotted
785      })
786      .alignItems(HorizontalAlign.Center)
787      .justifyContent(FlexAlign.Center)
788
789    }.width('100%').height('100%')
790  }
791}
792```
793
794![imageDrag.gif](figures/imageDrag.gif)
795
796### 示例8(设置图片拖拽震动)
797示例8通过设置enableHapticFeedback实现图片拖拽的震动效果。
798```ts
799// xxx.ets
800@Entry
801@Component
802struct DragPreviewDemo{
803  @Builder MenuBuilder() {
804    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
805      Text("menu item 1")
806        .fontSize(15)
807        .width(100)
808        .height(40)
809        .textAlign(TextAlign.Center)
810        .fontColor(Color.Black)
811        .backgroundColor(Color.Pink)
812      Divider()
813        .height(5)
814      Text("menu item 2")
815        .fontSize(15)
816        .width(100)
817        .height(40)
818        .textAlign(TextAlign.Center)
819        .fontColor(Color.Black)
820        .backgroundColor(Color.Pink)
821    }
822    .width(100)
823  }
824
825  build() {
826    Row() {
827      Column() {
828        Image($r('app.media.app_icon'))
829          .width("30%")
830          .draggable(true)
831          .dragPreviewOptions({}, {isMultiSelectionEnabled:true, defaultAnimationBeforeLifting:true, enableHapticFeedback: true})
832          .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
833          .onDragStart(() => {
834            console.info("Image onDragStart")
835          })
836      }
837      .width("100%")
838    }
839    .height("100%")
840  }
841}
842```
843
844### 示例9(自定义预览图)
845示例9通过配置onlyForLifting实现自定义预览图,仅用于浮起效果以及配置isLiftingDisabled实现禁用浮起效果。
846```ts
847// xxx.ets
848@Entry
849@Component
850struct LiftingExampleDemo {
851  @Builder
852  dragPreviewBuilder() {
853    Column() {
854      Text("dragPreview builder")
855        .width(150)
856        .height(50)
857        .fontSize(20)
858        .borderRadius(10)
859        .textAlign(TextAlign.Center)
860        .fontColor(Color.Black)
861        .backgroundColor(Color.Green)
862    }
863  }
864  @Builder
865  MenuBuilder() {
866    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
867      Text("menu 1")
868        .fontSize(25)
869        .width(200)
870        .height(60)
871        .textAlign(TextAlign.Center)
872        .fontColor(Color.Black)
873        .backgroundColor(Color.Green)
874      Divider()
875        .height(5)
876      Text("menu 2")
877        .fontSize(25)
878        .width(200)
879        .height(60)
880        .textAlign(TextAlign.Center)
881        .fontColor(Color.Black)
882        .backgroundColor(Color.Green)
883    }
884    .width(100)
885  }
886  build() {
887    Column() {
888      Column() {
889        Text("禁用浮起效果")
890          .fontSize(30)
891          .height(30)
892          .backgroundColor('#FFFFFF')
893          .margin({ top: 30 })
894        Image($r('app.media.startIcon'))
895          .width("40%")
896          .draggable(true)
897          .margin({ top: 15 })
898          .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
899          .onDragStart(() => {
900          })
901          .dragPreviewOptions({}, {
902            isLiftingDisabled: true
903          })
904          .dragPreview(this.dragPreviewBuilder, {
905            onlyForLifting: true,
906            delayCreating: true
907          })
908      }.width("%")
909      Column() {
910        Text("仅用于浮起效果")
911          .fontSize(30)
912          .height(30)
913          .backgroundColor('#FFFFFF')
914          .margin({ top: 80 })
915        Image($r('app.media.startIcon'))
916          .width("40%")
917          .draggable(true)
918          .margin({ top: 15 })
919          .onDragStart(() => {
920          })
921          .dragPreviewOptions({}, {
922            isLiftingDisabled: false
923          })
924          .dragPreview(this.dragPreviewBuilder, {
925            onlyForLifting: true,
926            delayCreating: true
927          })
928      }.width("100%")
929    }.height("100%")
930  }
931}
932```
933
934自定义预览图用于浮起效果。
935
936![onlyForLifting.gif](figures/onlyForLifting.gif)
937
938自定义预览图禁用浮起效果。
939
940![isLiftingDisabled.gif](figures/isLiftingDisabled.gif)
941
942### 示例10(以拖拽预览图初始尺寸计算跟手点位置)
943示例10通过配置DragPreviewMode.ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW实现根据拖拽预览图的初始尺寸来计算拖拽过程中跟手点位置。当设置DragPreviewMode.ENABLE_MULTI_TILE_EFFECT时,该属性不生效。
944```ts
945@Entry
946@Component
947struct Index {
948  private iconStr: ResourceStr = $r("app.media.app_icon")
949
950  @Builder
951  MyPreview() {
952    Image($r('app.media.image'))
953      .width(100)
954      .height(100)
955  }
956
957  @Builder
958  MyMenuPreview() {
959    Column() {
960      Image($r('app.media.image'))
961        .width(100)
962        .height(100)
963    }
964    .backgroundColor(Color.Green)
965    .width(300)
966    .height(300)
967  }
968
969  @Builder
970  MyMenu() {
971    Menu() {
972      MenuItem({ startIcon: this.iconStr, content: "菜单选项" })
973      MenuItem({ startIcon: this.iconStr, content: "菜单选项" })
974    }
975  }
976
977  @Builder
978  SubMenu() {
979    Menu() {
980      MenuItem({ content: "复制", labelInfo: "Ctrl+C" })
981      MenuItem({ content: "粘贴", labelInfo: "Ctrl+V" })
982    }
983  }
984
985  build() {
986    NavDestination() {
987      Scroll() {
988        Column() {
989          Text("no ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW")
990          Image($r('app.media.image'))
991            .width(200)
992            .height(200)
993            .bindContextMenu(this.MyMenu, ResponseType.LongPress, {
994              preview: this.MyPreview
995            })
996            .dragPreview(this.MyMenuPreview)
997            .draggable(true)
998
999          Text("ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW")
1000          Image($r('app.media.image'))
1001            .width(200)
1002            .height(200)
1003            .bindContextMenu(this.MyMenu, ResponseType.LongPress, {
1004              preview: this.MyPreview
1005            })
1006            .dragPreview(this.MyMenuPreview)
1007            .draggable(true)
1008            .dragPreviewOptions({
1009              mode: [DragPreviewMode.ENABLE_TOUCH_POINT_CALCULATION_BASED_ON_FINAL_PREVIEW]
1010            })
1011        }.width('100%')
1012      }
1013    }
1014    .height('100%')
1015    .width('100%')
1016  }
1017}
1018```
1019
1020![touchPointer.gif](figures/touchPointer.gif)
1021
1022### 示例11(长按浮起预览图与拖拽预览图过渡动效)
1023示例11通过配置DraggingSizeChangeEffect实现不同拖拽过渡效果。
1024```ts
1025@Entry
1026@Component
1027struct Index {
1028  private iconStr: ResourceStr = $r("app.media.app_icon")
1029
1030  @Builder
1031  MyPreview() {
1032    Image($r('app.media.image'))
1033      .width(200)
1034      .height(200)
1035  }
1036
1037  @Builder
1038  MyMenuPreviewSame() {
1039    Column() {
1040      Image($r('app.media.image'))
1041        .width(300)
1042        .height(300)
1043    }
1044  }
1045
1046  @Builder
1047  MyMenuPreview() {
1048    Column() {
1049      Image($r('app.media.startIcon'))
1050        .width(300)
1051        .height(300)
1052    }
1053  }
1054
1055  @Builder
1056  MyMenu() {
1057    Menu() {
1058      MenuItem({ startIcon: this.iconStr, content: "菜单选项" })
1059      MenuItem({ startIcon: this.iconStr, content: "菜单选项" })
1060    }
1061  }
1062
1063  @Builder
1064  SubMenu() {
1065    Menu() {
1066      MenuItem({ content: "复制", labelInfo: "Ctrl+C" })
1067      MenuItem({ content: "粘贴", labelInfo: "Ctrl+V" })
1068    }
1069  }
1070
1071  build() {
1072    Column() {
1073      Text("sizeChangeEffect: SIZE_TRANSITION,长按弹出菜单,拖拽移动后菜单预览图过渡到预览图,有缩放无叠加效果")
1074        .margin({ top: 10 })
1075      Image($r('app.media.image'))
1076        .width(200)
1077        .height(200)
1078        .bindContextMenu(this.MyMenu, ResponseType.LongPress, {
1079          preview: this.MyMenuPreviewSame
1080        })
1081        .dragPreview(this.MyPreview)
1082        .dragPreviewOptions({
1083          sizeChangeEffect: DraggingSizeChangeEffect.SIZE_TRANSITION
1084        })
1085        .draggable(true)
1086
1087      Text("sizeChangeEffect: SIZE_CONTENT_TRANSITION,长按弹出菜单,拖拽移动后菜单预览图和拖拽预览图两层叠加过渡")
1088        .margin({ top: 10 })
1089      Image($r('app.media.image'))
1090        .width(200)
1091        .height(200)
1092        .bindContextMenu(this.MyMenu, ResponseType.LongPress, {
1093          preview: this.MyMenuPreview
1094        })
1095        .dragPreview(this.MyPreview)
1096        .dragPreviewOptions({
1097          sizeChangeEffect: DraggingSizeChangeEffect.SIZE_CONTENT_TRANSITION
1098        })
1099        .draggable(true)
1100    }
1101    .height('100%')
1102    .width('100%')
1103  }
1104}
1105```
1106
1107![sizeChangeEffect.gif](figures/sizeChangeEffect.gif)