OpenHarmony实战开发-如何在网格Grid中通过拖拽交换子组件位置

567 篇文章 4 订阅
555 篇文章 0 订阅

场景说明

在使用网格Grid的应用中,可以通过拖拽子组件GridItem的方式,交换子组件的显示位置。

效果呈现

本示例在模拟器中显示的最终效果如下(预览器中显示效果略有差异):

在这里插入图片描述

运行环境

  • IDE:DevEco Studio 3.1 Beta2
  • SDK:Ohos_sdk_public 3.2.11.9 (API Version9 Release)

实现原理

1.设置Grid的editMode属性为true,使Grid进入编辑模式,从而可以拖拽Grid组件内部GridItem。

2.在Grid的相关拖拽事件中进行拖拽逻辑处理:

1.在onItemDragStart事件中显示拖拽过程中的图片,即被拖拽的GridItem。

2.在onItemDrop事件中根据拖拽前后的位置,完成两个GridItem位置交换的逻辑。

开发步骤

1.构建Grid组件及子组件GridItem,开启Grid组件的editMode属性。

build() {
  Column({ space: 5 }) {
    Grid(this.scroller) {
      ForEach(this.numbers, (day: string) => {
        GridItem() {
          ...
        }
      })
    }
    .editMode(true)
    ...

  }.width('100%').margin({ top: 5 })
}

2.当长按GridItem时触发onItemDragStart事件,在该事件中提供被拖拽GridItem的显示逻辑。

.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
  return this.pixelMapBuilder()
})

其中,pixelMapBuilder构造拖拽过程中显示的图片,即被拖拽的GridItem。

@State text: string = 'drag'

@Builder pixelMapBuilder() {
  Column() {
    Text(this.text)
      .fontSize(16)
      .backgroundColor(0xF9CF93)
      .width(80)
      .height(80)
      .textAlign(TextAlign.Center)
  }
}

拖拽过程中GridItem显示的内容,在触摸事件发生时进行传递。

ForEach(this.numbers, (day: string) => {
  GridItem() {
    Text(day)
      ...
      .onTouch((event: TouchEvent) => {
        if (event.type === TouchType.Down) {
          this.text = day
        }
      })
  }
})

3.停止拖拽时触发onItemDrop事件,在该事件中完成两个GridItem位置交换的逻辑。

为了防止GridItem被拖拽到空白的区域,在交换之前判断拖拽插入的位置是否超出当前已有内容的范围:

.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
  if(insertIndex < this.numbers.length){
    this.changeIndex(itemIndex, insertIndex)
  }
})

其中,changeIndex为具体交换数组元素位置的逻辑:

changeIndex(index1: number, index2: number) {
  [this.numbers[index1], this.numbers[index2]] = [this.numbers[index2], this.numbers[index1]];
}

完整代码

通过上述步骤可以完成整个示例的开发,完整代码如下:

@Entry
@Component
struct Index {
  @State numbers: String[] = []
  scroller: Scroller = new Scroller()
  @State text: string = 'drag'

  //拖拽过程中展示的样式
  @Builder pixelMapBuilder() {
    Column() {
      Text(this.text)
        .fontSize(16)
        .backgroundColor(0xF9CF93)
        .width(80)
        .height(80)
        .textAlign(TextAlign.Center)
    }
  }

  aboutToAppear() {
    for (let i = 1;i <= 15; i++) {
      this.numbers.push(i + '')
    }
  }

  //交换数组中元素位置
  changeIndex(index1: number, index2: number) {
    [this.numbers[index1], this.numbers[index2]] = [this.numbers[index2], this.numbers[index1]];
  }

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller) {
        ForEach(this.numbers, (day: string) => {
          GridItem() {
            Text(day)
              .fontSize(16)
              .backgroundColor(0xF9CF93)
              .width(80)
              .height(80)
              .textAlign(TextAlign.Center)
              .onTouch((event: TouchEvent) => {
                if (event.type === TouchType.Down) {
                  this.text = day
                }
              })
          }
        })
      }
      .columnsTemplate('1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .onScrollIndex((first: number) => {
        console.info(first.toString())
      })
      .width('90%')
      .backgroundColor(0xFAEEE0)
      .height('100%')
      //设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem
      .editMode(true)
      //第一次拖拽此事件绑定的组件时,触发回调
      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
        //设置拖拽过程中显示的图片
        return this.pixelMapBuilder()
      })
      //绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调
      //itemIndex为拖拽起始位置,insertIndex为拖拽插入位置
      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
        //不支持拖拽到已有内容以外的位置
        if(insertIndex < this.numbers.length){
          this.changeIndex(itemIndex, insertIndex)
        }
      })
    }.width('100%').margin({ top: 5 })
  }
}

我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI、实战开发视频教程》以及《鸿蒙生态应用开发白皮书V2.0PDF》《鸿蒙开发学习手册》(共计890页)鸿蒙开发资料等…希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG

在这里插入图片描述

应用开发中级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

应用开发中高级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

南北双向高工技能基础:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

全网首发-工业级 南向设备开发就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值