1# 拖拽控制 2 3设置组件是否可以响应拖拽事件。 4 5> **说明:** 6> 7> 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9ArkUI框架对以下组件实现了默认的拖拽能力,支持对数据的拖出或拖入响应,开发者只需要将这些组件的draggable属性设置为true,即可使用默认拖拽能力。 10 11- 默认支持拖出能力的组件(可从组件上拖出数据):[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)、[FormComponent](ts-basic-components-formcomponent-sys.md)、[Hyperlink](ts-container-hyperlink.md) 12 13- 默认支持拖入能力的组件(目标组件可响应拖入数据):[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[Video](ts-media-components-video.md) 14 15开发者也可以通过实现通用拖拽事件来自定义拖拽响应。 16 17其他组件需要开发者将draggable属性设置为true,并在onDragStart等接口中实现数据传输相关内容,才能正确处理拖拽。 18 19## allowDrop 20 21allowDrop(value: Array<UniformDataType>) 22 23设置该组件上允许落入的数据类型。 24 25**系统能力:** SystemCapability.ArkUI.ArkUI.Full 26 27**参数:** 28 29| 参数名 | 类型 | 必填 | 说明 | 30| ------ | ------------------------------------------------------------ | ---- | ----------------------------------------------- | 31| value | Array\<[UniformDataType](../../apis-arkdata/js-apis-data-uniformTypeDescriptor.md#uniformdatatype)> | 是 | 设置该组件上允许落入的数据类型。<br/>默认值:空 | 32 33## draggable 34 35draggable(value: boolean) 36 37设置该组件是否允许进行拖拽。 38 39**系统能力:** SystemCapability.ArkUI.ArkUI.Full 40 41**参数:** 42 43| 参数名 | 类型 | 必填 | 说明 | 44| ------ | ------- | ---- | ---------------------------------------------- | 45| value | boolean | 是 | 设置该组件是否允许进行拖拽。<br/>默认值:false | 46 47## dragPreview<sup>11+</sup> 48 49dragPreview(value: CustomBuilder | DragItemInfo) 50 51设置组件拖拽过程中的预览图。 52 53**系统能力:** SystemCapability.ArkUI.ArkUI.Full 54 55**参数:** 56 57| 参数名 | 类型 | 必填 | 说明 | 58| ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 59| value | [CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](ts-universal-events-drag-drop.md#dragiteminfo说明) | 是 | 设置组件拖拽过程中的预览图,仅在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/js-apis-image.md#pixelmap7)方式。<br/>默认值:空<br/> | 60 61## dragPreviewOptions<sup>11+</sup> 62 63dragPreviewOptions(value: DragPreviewOptions) 64 65设置拖拽过程中背板图处理模式,仅在onDragStart拖拽方式有效。 66 67**系统能力:** SystemCapability.ArkUI.ArkUI.Full 68 69**参数:** 70 71| 参数名 | 类型 | 必填 | 说明 | 72| ------ | --------------------------------------------------------- | ---- | ------------------------------------------------------------ | 73| value | [DragPreviewOptions](#dragpreviewoptions11)<sup>11+</sup> | 是 | 设置拖拽过程中背板图处理模式。<br/>默认值:空 | 74 75## DragPreviewOptions<sup>11+</sup> 76 77| 名称 | 类型 | 必填 | 描述 | 78| -------- | -------- | -------- | -------- | 79| mode | [DragPreviewMode](#dragpreviewmode11枚举说明) | 否 | 表示拖拽过程中背板图处理模式。<br/>默认值:DragPreviewMode.AUTO<br/> | 80 81## DragPreviewMode<sup>11+</sup>枚举说明 82 83| 名称 | 枚举值 | 描述 | 84| -------- | ------- | -------- | 85| AUTO | 1 | 系统根据拖拽场景自动改变跟手点位置,根据规则自动对拖拽背板图进行缩放变换等。 | 86| DISABLE_SCALE | 2 | 禁用系统对拖拽背板图的缩放行为。 | 87 88## 示例 89### 示例1 90allowDrop与draggable属性用法示例 91 92```ts 93// xxx.ets 94import UDC from '@ohos.data.unifiedDataChannel'; 95import UTD from '@ohos.data.uniformTypeDescriptor'; 96 97@Entry 98@Component 99struct ImageExample { 100 @State uri: string = "" 101 @State AblockArr: string[] = [] 102 @State BblockArr: string[] = [] 103 @State AVisible: Visibility = Visibility.Visible 104 @State dragSuccess :Boolean = false 105 106 build() { 107 Column() { 108 Text('Image拖拽') 109 .fontSize('30dp') 110 Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) { 111 Image($r('app.media.icon')) 112 .width(100) 113 .height(100) 114 .border({ width: 1 }) 115 .visibility(this.AVisible) 116 .draggable(true) 117 .onDragEnd((event: DragEvent) => { 118 let ret = event.getResult(); 119 if(ret == 0) { 120 console.log("enter ret == 0") 121 this.AVisible = Visibility.Hidden; 122 } else { 123 console.log("enter ret != 0") 124 this.AVisible = Visibility.Visible; 125 } 126 }) 127 } 128 .margin({ bottom: 20 }) 129 Row() { 130 Column(){ 131 Text('不允许释放区域(显示不允许角标但可以释放)') 132 .fontSize('15dp') 133 .height('10%') 134 List(){ 135 ForEach(this.AblockArr, (item:string, index) => { 136 ListItem() { 137 Image(item) 138 .width(100) 139 .height(100) 140 .border({width: 1}) 141 } 142 .margin({ left: 30 , top : 30}) 143 }, (item:string) => item) 144 } 145 .height('90%') 146 .width('100%') 147 .allowDrop([UTD.UniformDataType.TEXT]) 148 .onDrop((event?: DragEvent, extraParams?: string) => { 149 this.uri = JSON.parse(extraParams as string).extraInfo; 150 this.AblockArr.splice(JSON.parse(extraParams as string).insertIndex, 0, this.uri); 151 console.log("ondrop not udmf data"); 152 }) 153 .border({width: 1}) 154 } 155 .height("50%") 156 .width("45%") 157 .border({ width: 1 }) 158 .margin({ left: 12 }) 159 Column(){ 160 Text('可释放区域') 161 .fontSize('15dp') 162 .height('10%') 163 List(){ 164 ForEach(this.BblockArr, (item:string, index) => { 165 ListItem() { 166 Image(item) 167 .width(100) 168 .height(100) 169 .border({width: 1}) 170 } 171 .margin({ left: 30 , top : 30}) 172 }, (item:string) => item) 173 } 174 .border({width: 1}) 175 .height('90%') 176 .width('100%') 177 .allowDrop([UTD.UniformDataType.IMAGE]) 178 .onDrop((event?: DragEvent, extraParams?: string) => { 179 console.log("enter onDrop") 180 let dragData:UnifiedData = (event as DragEvent).getData() as UnifiedData; 181 if(dragData != undefined) { 182 let arr:Array<UDC.UnifiedRecord> = dragData.getRecords(); 183 if(arr.length > 0) { 184 let image = arr[0] as UDC.Image; 185 this.uri = image.imageUri; 186 this.BblockArr.splice(JSON.parse(extraParams as string).insertIndex, 0, this.uri); 187 } else { 188 console.log(`dragData arr is null`) 189 } 190 } else { 191 console.log(`dragData is undefined`) 192 } 193 console.log("ondrop udmf data"); 194 this.dragSuccess = true 195 }) 196 } 197 .height("50%") 198 .width("45%") 199 .border({ width: 1 }) 200 .margin({ left: 12 }) 201 } 202 }.width('100%') 203 } 204} 205``` 206 207 208 209### 示例2 210dragPreview属性用法示例 211```ts 212// xxx.ets 213@Entry 214@Component 215struct DragPreviewDemo{ 216 @Builder dragPreviewBuilder() { 217 Column() { 218 Text("dragPreview") 219 .width(150) 220 .height(50) 221 .fontSize(20) 222 .borderRadius(10) 223 .textAlign(TextAlign.Center) 224 .fontColor(Color.Black) 225 .backgroundColor(Color.Pink) 226 } 227 } 228 229 @Builder MenuBuilder() { 230 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 231 Text("menu item 1") 232 .fontSize(15) 233 .width(100) 234 .height(40) 235 .textAlign(TextAlign.Center) 236 .fontColor(Color.Black) 237 .backgroundColor(Color.Pink) 238 Divider() 239 .height(5) 240 Text("menu item 2") 241 .fontSize(15) 242 .width(100) 243 .height(40) 244 .textAlign(TextAlign.Center) 245 .fontColor(Color.Black) 246 .backgroundColor(Color.Pink) 247 } 248 .width(100) 249 } 250 251 build() { 252 Row() { 253 Column() { 254 Image('/resource/image.jpeg') 255 .width("30%") 256 .draggable(true) 257 .bindContextMenu(this.MenuBuilder, ResponseType.LongPress) 258 .onDragStart(() => { 259 console.log("Image onDragStart") 260 }) 261 .dragPreview(this.dragPreviewBuilder) 262 } 263 .width("100%") 264 } 265 .height("100%") 266 } 267} 268``` 269 270 271 272### 示例3 273dragPreviewOptions属性用法示例 274```ts 275// xxx.ets 276@Entry 277@Component 278struct dragPreviewOptionsDemo{ 279 build() { 280 Row() { 281 Column() { 282 Image('/resource/image.jpeg') 283 .margin({ top: 10 }) 284 .width("100%") 285 .draggable(true) 286 .dragPreviewOptions({ mode: DragPreviewMode.AUTO }) 287 } 288 .width("100%") 289 .height("100%") 290 } 291 } 292} 293``` 294 295