简介

该文主要提供图文拖拽的场景及最佳实践示例。

开发环境

DevEco Studio: DevEco Studio NEXT Release(Build Version: 5.0.3.900)

系统: OpenHarmony 5.0.0.71

设备: DAYU200(rk3568)

最佳实践示例

图文拖入时,需要将dragEvent中的数据的图文分开依次处理。

Text组件拖拽

import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
import common from '@ohos.app.ability.common';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct DragTest7 {
  @State targetImage: string | PixelMap | null = null;
  @State targetTextContent: string = "图文落入框";
  @State imageWidth: number = 200;
  @State imageHeight: number = 200;
  @State isDraggable: boolean = true
  @State opacityValue: number = 1;
  private context = getContext(this) as common.UIAbilityContext

  async createPixelMap(pixelMap: unifiedDataChannel.SystemDefinedPixelMap): Promise<image.PixelMap | null> {
    let mWidth: number = (pixelMap.details?.width ?? -1) as number;
    let mHeight: number = (pixelMap.details?.height ?? -1) as number;
    let mPixelFormat: image.PixelMapFormat =
      (pixelMap.details?.['pixel-format'] ?? image.PixelMapFormat.UNKNOWN) as image.PixelMapFormat;
    let mItemPixelMapData: Uint8Array = pixelMap.rawData;
    const opts: image.InitializationOptions = {
      editable: false, pixelFormat: mPixelFormat, size: {
        height: mHeight,
        width: mWidth
      }
    };
    const buffer: ArrayBuffer = mItemPixelMapData.buffer.slice(mItemPixelMapData.byteOffset,
      mItemPixelMapData.byteLength + mItemPixelMapData.byteOffset);
    try {
      let pixelMap: image.PixelMap = await image.createPixelMap(buffer, opts);
      return pixelMap;
    } catch (err) {
      return null;
    }
  }

  build() {
    NavDestination() {
      Column() {
        Column() {
          // 图文拖出
          Column() {
            Text('原图文').fontSize(12).fontColor(0xCCCCCC).width('100%').padding({ left: 20 })
            Text() {
              Span('测试图文拖拽').fontSize(50)
              ImageSpan(this.context.resourceManager.getDrawableDescriptor($r('app.media.startIcon').id).getPixelMap())
                .width(200)
                .height(200)
                .border({ radius: 8 })
            }
            .copyOption(CopyOptions.InApp)
            .draggable(true)
            .opacity(this.opacityValue)
            .onDragLeave((_event: DragEvent) => {
              console.info('dragtest onDragMove')
              this.opacityValue = 0.4
            })
            .onDragMove((_event: DragEvent) => {
              console.info('dragtest onDragMove')
              this.opacityValue = 0.4
            })
            .copyOption(CopyOptions.InApp)
          }

          // 图文拖入
          Column() {
            Text('图文落入框').fontSize(12).fontColor(0xCCCCCC).width('100%').padding({ left: 20 })
            Text() {
              Span(this.targetTextContent)
              ImageSpan(this.targetImage)
                .width(this.imageWidth).height(this.imageHeight)
                .visibility(this.targetImage === null ? Visibility.Hidden : Visibility.Visible)
            }
            .copyOption(CopyOptions.InApp)
            .draggable(true)
          }
          .allowDrop([uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP,
            uniformTypeDescriptor.UniformDataType.IMAGE,
            uniformTypeDescriptor.UniformDataType.PLAIN_TEXT,
            uniformTypeDescriptor.UniformDataType.TEXT])
          .onDragMove((_event: DragEvent) => {
            this.opacityValue = 0.4
          })
          .onDrop(async (event: DragEvent) => {
            console.info('dragtest start onDrop')
            let dragData = event.getData();
            if (dragData != undefined) {
              let records = dragData.getRecords();
              for (let i = 0; i < records.length; i++) {
                console.info('dragtest get records', JSON.stringify(i))
                let type = records[i].getType();
                switch (type) {
                  case uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP:
                    console.info('dragtest type is PIXEL_MAP')
                    let record: unifiedDataChannel.SystemDefinedPixelMap = (records[i]) as unifiedDataChannel.SystemDefinedPixelMap;
                    this.targetImage = await this.createPixelMap(record)
                    break;
                  case uniformTypeDescriptor.UniformDataType.IMAGE:
                    console.info('dragtest type is IMAGE')
                    let udmfImage: unifiedDataChannel.Image = (records[i]) as unifiedDataChannel.Image;
                    this.targetImage = udmfImage.imageUri;
                    break;
                  case uniformTypeDescriptor.UniformDataType.PLAIN_TEXT:
                    console.info('dragtest type is PLAIN_TEXT')
                    let plainText: unifiedDataChannel.PlainText = records[i] as unifiedDataChannel.PlainText;
                    this.targetTextContent = plainText.textContent;
                    console.log('dragtest targetTextContent:' + this.targetTextContent);
                    break;
                  case uniformTypeDescriptor.UniformDataType.TEXT:
                    console.info('dragtest type is TEXT')
                    let currentText: unifiedDataChannel.Text = records[i] as unifiedDataChannel.Text;
                    let text: string = !!currentText.details ? currentText.details['value'] : '';
                    this.targetTextContent = this.targetTextContent.concat(text);
                    console.log('dragtest targetTextContent:' + this.targetTextContent);
                    break;
                  default:
                    console.info('dragtest type is error')
                    return;
                }
              }
              event.setResult(0)
              this.opacityValue = 1
            }
          })
          .width(300)
          .height(300)
          .border({ width: 1, radius: 5, style: BorderStyle.Dashed })
        }.justifyContent(FlexAlign.SpaceBetween)
        .layoutWeight(1)
        .margin({ bottom: 10 })
      }.width("100%").height('100%')

    }
    .title('图文拖拽示例')
  }
}

RichEditor组件拖拽

import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';
import { image } from '@kit.ImageKit';

@Entry
@Component
export struct DragTest8 {
  @State targetImage: string | PixelMap | null = null;
  @State targetTextContent: string = "";
  @State imageWidth: number = 200;
  @State imageHeight: number = 200;
  @State isDraggable: boolean = true
  @State opacityValue: number = 1;
  sourceController: RichEditorController = new RichEditorController();
  targetController: RichEditorController = new RichEditorController();
  private context = getContext(this) as common.UIAbilityContext

  async createPixelMap(pixelMap: unifiedDataChannel.SystemDefinedPixelMap): Promise<image.PixelMap | null> {
    let mWidth: number = (pixelMap.details?.width ?? -1) as number;
    let mHeight: number = (pixelMap.details?.height ?? -1) as number;
    let mPixelFormat: image.PixelMapFormat =
      (pixelMap.details?.['pixel-format'] ?? image.PixelMapFormat.UNKNOWN) as image.PixelMapFormat;
    let mItemPixelMapData: Uint8Array = pixelMap.rawData;
    const opts: image.InitializationOptions = {
      editable: false, pixelFormat: mPixelFormat, size: {
        height: mHeight,
        width: mWidth
      }
    };
    const buffer: ArrayBuffer = mItemPixelMapData.buffer.slice(mItemPixelMapData.byteOffset,
      mItemPixelMapData.byteLength + mItemPixelMapData.byteOffset);
    try {
      let pixelMap: image.PixelMap = await image.createPixelMap(buffer, opts);
      return pixelMap;
    } catch (err) {
      return null;
    }
  }

  build() {
    NavDestination() {
      Column() {
        Column() {
          // 图文拖出
          Column() {
            Text('富文本区域图片').fontSize(12).fontColor(0xCCCCCC).width('100%').padding({ left: 20 })
            RichEditor({ controller: this.sourceController })
              .draggable(true)
              .copyOptions(CopyOptions.InApp)
              .onReady(() => {
                this.sourceController.addTextSpan("012345",
                  {
                    style:
                    {
                      fontColor: Color.Orange,
                      fontSize: 30
                    }
                  })
                this.sourceController.addImageSpan(
                  this.context.resourceManager.getDrawableDescriptor($r('app.media.startIcon').id).getPixelMap(),
                  {
                    imageStyle:
                    {
                      size: ["157px", "157px"]
                    }
                  })
              })
          }

          // 图文拖入
          Column() {
            Text('图文落入框').fontSize(12).fontColor(0xCCCCCC).width('100%').padding({ left: 20 })
            RichEditor({ controller: this.targetController })
              .draggable(true)
              .copyOptions(CopyOptions.InApp)
          }
          .allowDrop([uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP,
            uniformTypeDescriptor.UniformDataType.IMAGE,
            uniformTypeDescriptor.UniformDataType.PLAIN_TEXT,
            uniformTypeDescriptor.UniformDataType.TEXT])
          .onDragMove((_event: DragEvent) => {
            this.opacityValue = 0.4
          })
          .onDrop(async (event: DragEvent) => {
            console.info('dragtest start onDrop')
            let dragData = event.getData();
            this.targetController.getCaretOffset();
            if (dragData != undefined) {
              let records = dragData.getRecords();
              for (let i = 0; i < records.length; i++) {
                console.info('dragtest get records', JSON.stringify(i))
                let type = records[i].getType();
                switch (type) {
                  case uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP:
                    console.info('dragtest type is PIXEL_MAP')
                    let record: unifiedDataChannel.SystemDefinedPixelMap = (records[i]) as unifiedDataChannel.SystemDefinedPixelMap;
                    this.targetImage = await this.createPixelMap(record);
                    this.targetController.addImageSpan(this.targetImage,
                      {
                        imageStyle:
                        {
                          size: ["175px", "175px"]
                        },
                        offset: this.targetController.getCaretOffset()
                      })
                    break;
                  case uniformTypeDescriptor.UniformDataType.IMAGE:
                    console.info('dragtest type is IMAGE')
                    let image: unifiedDataChannel.Image = (records[i]) as unifiedDataChannel.Image;
                    this.targetImage = image.imageUri;
                    this.targetController.addImageSpan(this.targetImage,
                      {
                        imageStyle:
                        {
                          size: ["175px", "175px"]
                        },
                        offset: this.targetController.getCaretOffset()
                      })
                    break;
                  case uniformTypeDescriptor.UniformDataType.PLAIN_TEXT:
                    console.info('dragtest type is PLAIN_TEXT')
                    let plainText: unifiedDataChannel.PlainText = records[i] as unifiedDataChannel.PlainText;
                    this.targetTextContent = plainText.textContent;
                    console.log('dragtest targetTextContent:' + this.targetTextContent);
                    this.targetController.addTextSpan(this.targetTextContent,
                      {
                        style:
                        {
                          fontColor: Color.Orange,
                          fontSize: 30
                        },
                        offset: this.targetController.getCaretOffset()
                      })
                    break;
                  case uniformTypeDescriptor.UniformDataType.TEXT:
                    console.info('dragtest type is TEXT')
                    let currentText: unifiedDataChannel.Text = records[i] as unifiedDataChannel.Text;
                    let text: string = !!currentText.details ? currentText.details['value'] : '';
                    this.targetTextContent = this.targetTextContent.concat(text);
                    console.log('dragtest targetTextContent:' + this.targetTextContent);
                    this.targetController.addTextSpan(this.targetTextContent,
                      {
                        style:
                        {
                          fontColor: Color.Orange,
                          fontSize: 30
                        },
                        offset: this.targetController.getCaretOffset()
                      })
                    break;
                  default:
                    console.info('dragtest type is error')
                    return;
                }
              }
              event.setResult(0)
              this.opacityValue = 1
            }
            this.targetTextContent = "";
            this.targetImage = null;
          })
          .width(300)
          .height(300)
          .border({ width: 1, radius: 5, style: BorderStyle.Dashed })
        }.justifyContent(FlexAlign.SpaceBetween)
        .layoutWeight(1)
        .margin({ bottom: 10 })
      }.width("100%").height('100%')
    }
    .title('富文本中图文拖拽示例')
  }
}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐