天津储鑫盛钢材现货供应商 发表于 2024-9-30 19:01:31

升级你的HarmonyOS体验:一窥功能引导与拖拽交换的独家本领

媒介

在当今的移动应用开辟范畴,为了提供更加友好和直观的用户体验,开辟者们通常会集成多种交互功能来增强应用的互动性和易用性。在这些功能中,有两个功能显得尤为重要,它们分别是功能引导和元素拖拽交换。功能引导帮助用户快速熟悉应用的各种操纵和特性,而元素拖拽交换则允许用户以直观的方式对界面元素进行个性化排序和布局。本文将深入探讨在HarmonyOS平台上怎样实现这两个关键功能。

项目目次布局


├── main
│   ├── ets
│   │   ├── entryability
│   │   │   └── EntryAbility.ets
│   │   ├── model
│   │   │   ├── AttributeModifier.ets         //声明GridItem动态属性
│   │   │   ├── GridItemDeletionCtrl.ets      // gridItem删除管理
│   │   │   ├── headerIcon.ets                // icon 布局区域
│   │   │   └── iconInfo.ets
│   │   └── pages
│   │       └── Index.ets                     // 入口区域

开辟流程

主要步调解说


[*]导入模块:代码首先导入了<font style="color:rgb(26, 32, 41);">@ohos/high_light_guide</font>模块中的多个类,用于创建和管理高亮引导,以及<font style="color:rgb(26, 32, 41);">@ohos.animator</font>模块中的动画参数设置。同时,还导入了自定义的<font style="color:rgb(26, 32, 41);">HeaderApp</font>模子和<font style="color:rgb(26, 32, 41);">promptAction</font>用于表现对话框。
[*]常量定义:定义了动画的持续时间、延迟、迭代次数、开始和结束的状态等常量。
[*]组件定义:使用<font style="color:rgb(26, 32, 41);">@Entry</font>和<font style="color:rgb(26, 32, 41);">@Component</font>装饰器定义了一个名为<font style="color:rgb(26, 32, 41);">Index</font>的布局体组件。
[*]成员变量:定义了用于构建和管理高亮引导的变量,以及动画参数、监听器等。
[*]**<font style="color:rgb(26, 32, 41);">aboutToAppear</font>**方法:在这个方法中,初始化了高亮引导构建器<font style="color:rgb(26, 32, 41);">HighLightGuideBuilder</font>,并设置了多个引导页面<font style="color:rgb(26, 32, 41);">GuidePage</font>,包括提示文本、高亮形状、动画效果等。
[*]**<font style="color:rgb(26, 32, 41);">build</font>**方法:构建了组件的UI布局,使用<font style="color:rgb(26, 32, 41);">Stack</font>布局包裹了一个<font style="color:rgb(26, 32, 41);">HighLightGuideComponent</font>,并设置了其属性和回调函数。
[*]布局构建器:定义了多个布局构建器方法(如<font style="color:rgb(26, 32, 41);">highLightComponent</font>、<font style="color:rgb(26, 32, 41);">firstHigh</font>、<font style="color:rgb(26, 32, 41);">secondHigh</font>、<font style="color:rgb(26, 32, 41);">thirdHigh</font>、<font style="color:rgb(26, 32, 41);">endHigh</font>),用于创建具体的引导页面布局和交互逻辑。
[*]**<font style="color:rgb(26, 32, 41);">endHigh</font>**方法:在最后一个引导页面表现时,通过<font style="color:rgb(26, 32, 41);">promptAction.showDialog</font>表现一个对话框,用户确认后移除高亮引导。
关键配置

项目中我们使用了高亮插件<font style="color:rgb(64, 72, 91);">ohos_highlightguide</font> , 在终端输入 指令
   ohpm install @ohos/high_light_guide
来下载依赖, 并进行相关配置, 如下图所示
https://img-blog.csdnimg.cn/img_convert/3ebbc8cd2146009055bf078adc5ad3c4.png

Index.ets 页面解说

Index 页面主要做的是高光处理 在页面加载的时间设定高光组件
aboutToAppear() {

    // 设定高光组件
    this.builder = new HighLightGuideBuilder()
      .setLabel('guide')
      .alwaysShow(true)// 总是显示,调试时可以打开
      .setOnGuideChangedListener(this.visibleChangeListener)
      .setOnPageChangedListener(this.pageChangeListener)
      .addGuidePage(GuidePage.newInstance()// 第一处提示 点击编辑
      .setEverywhereCancelable(true)// 允许点击任意处关闭
      .addHighLight('edit')
      .setHighLightIndicator(this.firstHigh)
      .setExitAnimation(this.exitAnimatorParam))
      .addGuidePage(GuidePage.newInstance() // 设定第二处提示
      .setEverywhereCancelable(true)// 允许点击任意处关闭
      .addHighLight( 'high', HighLightShape.OVAL , 20)
      .setHighLightIndicator(this.secondHigh)
      .setExitAnimation(this.exitAnimatorParam))
      .addGuidePage(GuidePage.newInstance()// 设定第三处提示
      .setEverywhereCancelable(false)// 要求用户点击"我知道了"才能关闭提示
      .setHighLightIndicator(this.thirdHigh)
      .setEnterAnimation(this.enterAnimatorParam)
      .setExitAnimation(this.exitAnimatorParam))
      .addGuidePage(GuidePage.newInstance()// 设定第四处提示 移除高亮引导
      .setEverywhereCancelable(false)
      .setHighLightIndicator(this.endHigh));
}

代码中 addGuidePage 指代的是每一个高光插件, 通过setHighLightIndicator来引用我们的高光的组件
高光组件相关

本次项目中主要用了 四个高光组件 , 每个组件都进行了不同的定义 , 从而来进行不同的高光展示
@Builder
firstHigh(){
   Column(){
       Image($r("app.media.first_high_icon")).width(20).height(30).margin({right:'20', bottom:'10'})
       Text($r('app.string.first_high_tip'))
         .textAlign(TextAlign.Center)
         .fontColor(Color.White)
         .textAlign(TextAlign.Start)
         .onClick(() => {
         if (this.controller) {
             this.controller.showPage(1);
         }
         })
   }
   .justifyContent(FlexAlign.End)
   .alignItems(HorizontalAlign.End)
   .width('50%')
   .margin({ left: $r('app.string.first_high_margin'),
       top:'50'
   })
}

@Builder
secondHigh() {
    Column() {
      Text('长按可拖动')
      .textAlign(TextAlign.Center)
      .fontColor(Color.White)
      .width('70%')
      .onClick(() => {
          if (this.controller) {
            this.controller.showPage(2);
          }
      })
         Image($r("app.media.second_high_icon"))
      .width($r('app.integer.sort_order_width'))
      .height($r('app.integer.sort_order_width'))
         .margin({top:10})
         .onClick(() => {
          if (this.controller) {
            this.controller.showPage(2);
          }
      })
    }
    .width($r('app.string.percent_one_hundred'))
    .margin({top:10})
    .alignItems(HorizontalAlign.Center)
    // position坐标是以页面顶部中心为原点,不包括系统状态栏
    // .position({ x: this.PosX, y: this.PosY})
}

@Builder
thirdHigh() {
    Column() {
      Text($r('app.string.third_high_tip'))
      .fontColor(Color.Black)
      .backgroundColor($r('app.color.module_back_ground'))
      .textAlign(TextAlign.Center)
      .width($r('app.integer.first_indicator_width'))
      .height($r('app.integer.first_indicator_height'))
      .borderRadius($r('app.integer.border_radius'))
   Button($r('app.string.third_high_btn'))
      .fontColor(Color.Black)
      .margin($r('app.integer.common_margin'))
      .fontSize($r('app.integer.access_font_size'))
      .backgroundColor($r('app.color.first_direct_background'))
      .border({ width: 1, color: Color.White })
      .width($r('app.integer.high_light_button_width'))
      .onClick(() => {
          if (this.controller) {
            this.controller.showPage(3);
          }
      })
    }
    .width($r('app.string.percent_one_hundred'))
    .height($r('app.string.percent_one_hundred'))
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
}

@Builder
endHigh() {
    Column()
      .onAppear(() => {
      promptAction.showDialog({
          message: $r("app.string.end_high_tip"),
          buttons: [
            {
            text: $r('app.string.confirm_btn'),
            color: $r('app.color.toast_success_back_ground')
            }
          ],
          isModal: false
      }).then(() => {
          if (this.controller) {
            this.controller.remove();
          }
      })
      })

}
HeaderApp

在HeaderApp 组件中主要实现的是元素切换功能 ,核心代码如下
Grid() {
      ForEach(this.AppDataArr, (item: AppInfo, index: number) => {
          GridItem() {
            IconWithNameView({ app: item })
          }
          .id(this.AppDataArr.indexOf(item) === SELECT_INDEX ? 'high' : '')
          .onAreaChange((oldValue: Area, newValue: Area) => {
            this.itemAreaWidth = Number(newValue.width);
          })
          .onTouch((event: TouchEvent) => {
            if (event.type === TouchType.Down) {
            this.movedItem = this.AppDataArr;
            }
          })
          .attributeModifier(this.GridItemDeletion.getModifier(item))
          .onClick(() => {
            if (!this.isEdit) {
            return;
            }
            this.GridItemDeletion.deleteGridItem(item, this.itemAreaWidth);
          })
      }, (item: AppInfo) => JSON.stringify(item))
      }
      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
      .width($r('app.string.grid_title_width'))
      .layoutWeight(1)
      .supportAnimation(true)
      .editMode(this.isEdit)
      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
      // 在onItemDragStart函数返回自定义组件,可在拖拽过程中显示此自定义组件。
      return this.pixelMapBuilder();
      })
      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
      //执行gridItem切换操作
      if (isSuccess && insertIndex < this.AppDataArr.length) {
          this.changeIndex(itemIndex, insertIndex);
      }
      })
代码中定义的id 属性 主要为了高光时的元素查找
通过 onItemDragStart 和 onItemDrop 来实现元素的切换效果
同时 IconWithNameView 定义的是每个组件相关的展示内容,代码如下
@Component
struct IconWithNameView {
private app: AppInfo = new AppInfo();
@Consume isEdit: boolean;

build() {
    Column() {
      Stack({ alignContent: Alignment.TopEnd }) {
      Image(this.app.icon)
          .width($r('app.string.icon_width'))
          .height($r('app.string.icon_height'))
          .interpolation(ImageInterpolation.High)
          .syncLoad(true)
          .draggable(false)
      if (this.isEdit) {
          Image($r('app.media.del_icon'))
            .width($r('app.string.del_icon_width'))
            .height($r('app.string.del_icon_height'))
            .markAnchor({ x: '-40%', y: '40%' })
            .draggable(false)
      }
      }

      Text(this.app.name)
      .width($r('app.string.icon_name_width'))
      .fontSize($r('app.string.icon_name_font_size'))
      .maxLines(1)
      .fontColor(Color.Black)
      .textAlign(TextAlign.Center)
      .margin({ top: 1 })
    }
    .width($r('app.string.icon_item_width'))
    .height($r('app.string.icon_item_height'))
    .justifyContent(FlexAlign.Center)
}
}
好了, 以上就是该项目标核心内容解说啦
总结

在harmonyos 逐渐强大的道路上每一份案例的支持都是尤为重要的, 等待每一位鸿蒙爱好者都贡献一份力量,共同美满harmonyos 的建设

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 升级你的HarmonyOS体验:一窥功能引导与拖拽交换的独家本领