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

文章目录

    • 前言
    • 项目目录结构
    • 开发流程
      • 主要步骤讲解
      • 关键配置
      • Index.ets 页面讲解
      • 高光组件相关
      • HeaderApp
    • 总结

前言

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

项目目录结构


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

开发流程

主要步骤讲解

  1. 导入模块:代码首先导入了<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>用于显示对话框。
  2. 常量定义:定义了动画的持续时间、延迟、迭代次数、开始和结束的状态等常量。
  3. 组件定义:使用<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>的结构体组件。
  4. 成员变量:定义了用于构建和管理高亮引导的变量,以及动画参数、监听器等。
  5. **<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>,包括提示文本、高亮形状、动画效果等。
  6. **<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>,并设置了其属性和回调函数。
  7. 布局构建器:定义了多个布局构建器方法(如<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>),用于创建具体的引导页面布局和交互逻辑。
  8. **<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

来下载依赖, 并进行相关配置, 如下图所示

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[index];
            }
          })
          .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 的建设

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/881830.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

故障诊断│GWO-DBN灰狼算法优化深度置信网络故障诊断

1.引言 随着人工智能技术的快速发展&#xff0c;深度学习已经成为解决复杂问题的热门方法之一。深度置信网络&#xff08;DBN&#xff09;作为深度学习中应用比较广泛的一种算法&#xff0c;被广泛应用于分类和回归预测等问题中。然而&#xff0c;DBN的训练过程通常需要大量的…

go 读取excel数据存储到mysql

一、安装依赖 go get github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx 二、main.go package mainimport ("fmt""github.com/jmoiron/sqlx""log" ) import "github.com/tealeg/xlsx" import _ "github.com/go-s…

【LeetCode热题100】位运算

这篇博客先介绍了常见位运算操作&#xff0c;然后记录了关于位运算的几道题&#xff0c;包括判定字符是否唯一、丢失的数字、两整数之和、只出现一次的数字2、消失的两个数字。 在这一部分&#xff0c;我们不妨先来总结一下常见位运算操作&#xff1a; 1.基础位运算 >>…

C++——模拟实现string

1.再谈string string为什么要被设计成模板&#xff1f;日常使用string好像都是char*&#xff0c;char*不够使用吗&#xff0c;为什么要设计成模板呢&#xff1f; 1.1 关于编码 //计算机的存储如何区分呢&#xff1f;int main() {//比如在C语言中&#xff0c;有整型//如果是有…

craco-less使用问题

craco-less使用问题 问题背景 前端是用React搭建&#xff0c;使用craco配置&#xff0c;相关库或插件版本如下 "craco/craco": "^7.1.0","react-scripts": "^5.0.1","craco-less": "^3.0.1"在生产环境&#xff…

P9235 [蓝桥杯 2023 省 A] 网络稳定性

*原题链接* 最小瓶颈生成树题&#xff0c;和货车运输完全一样。 先简化题意&#xff0c; 次询问&#xff0c;每次给出 &#xff0c;问 到 的所有路径集合中&#xff0c;最小边权的最大值。 对于这种题可以用kruskal生成树来做&#xff0c;也可以用倍增来写&#xff0c;但不…

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

SSM+vue音乐播放器管理系统

音乐播放器管理系统 随着社会的发展&#xff0c;计算机的优势和普及使得音乐播放器管理系统的开发成为必需。音乐播放器管理系统主要是借助计算机&#xff0c;通过对首页、音乐推荐、付费音乐、论坛信息、个人中心、后台管理等信息进行管理。减少管理员的工作&#xff0c;同时…

2024短剧系统开发,付费短剧小程序app源码教程,分销功能讲解搭建上线

短剧系统技术栈 前端&#xff1a;vue3uniapp 后端&#xff1a; php 数据库&#xff1a;mysql 服务器环境&#xff1a; centos7.6 宝塔 php7.4 MySQL5.7 一、短剧系统功能 短剧用户端&#xff1a; 小程序、抖音小程序、快手小程序、APP、 z付宝小程序 系统用户端详细功能&…

有关shell指令练习2

写一个shell脚本&#xff0c;将以下内容放到脚本中 在家目录下创建目录文件&#xff0c;dir dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中&#xff0c; 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz移动到dir1中 …

ABAP-Swagger 一种公开 ABAP REST 服务的方法

ABAP-Swagger An approach to expose ABAP REST services 一种公开 ABAP REST 服务的方法 Usage 1: develop a class in ABAP with public methods 2: implement interface ZIF_SWAG_HANDLER, and register the public methods(example method zif_swag_handler~meta) 3: …

nonlocal本质讲解(前篇)——从滤波到Nonlocal均值滤波

线性滤波 → \rightarrow →高斯滤波 → \rightarrow →高斯滤波 → \rightarrow →双边滤波 → \rightarrow →Nonlocal均值滤波 平均 高斯 双边 Nonlocal 目录 线性滤波高斯滤波双边滤波Nonlocal均值滤波 滤波最初是频域的概念&#xff0c;由于频域乘积对应空域卷积&am…

药物分子生成算法综述:从生成对抗网络到变换器模型的多样化选择

创作不易&#xff0c;您的打赏、关注、点赞、收藏和转发是我坚持下去的动力&#xff01; 基于已有的药物数据生成新的药物分子是一项复杂的任务&#xff0c;通常涉及到生成模型和机器学习算法。以下是一些常用的算法和方法&#xff1a; 1. 生成对抗网络 (GANs) 特点: 由生成…

罗马数字详解

一. 罗马数字の背景 1. 罗马数字的诞生与进化 罗马数字起源于古罗马帝国&#xff0c;拥有一个漫长而复杂的历史&#xff0c;始于公元前 8 世纪至 9 世纪&#xff0c;与古罗马帝国在帕兰丁山&#xff08;Palantine Hill&#xff09;周围建立的时间大致相同。不过&#xff0c;罗…

【GUI设计】基于Matlab的图像处理GUI系统(2),matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像处理GUI系统&#xff08;2&#xff09;&#xff0c;用matlab实现。…

jboss

一。CVE-2015-7501 1.POC&#xff0c;访问地址 192.168.10.193:8080/invoker/JMXInvokerServlet 返回如下&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 2.下载 ysoserial ⼯具进⾏漏洞利⽤ https://github.com/frohoff/ysoserial 将反弹shell进⾏base64编码…

java重点学习-设计模式

十三 设计模式 工厂模式&#xff1a;spring中使用&#xff08;目的是&#xff1a;解耦&#xff09; 1.简单工厂 所有的产品都共有一个工厂&#xff0c;如果新增产品&#xff0c;则需要修改代码&#xff0c;违反开闭原则是一种编程习惯&#xff0c;可以借鉴这种编程思路 2.工厂方…

基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图

实现基于北斗卫星的车辆定位和轨迹图的Maven工程&#xff08;使用模拟数据&#xff09;&#xff0c;我们将使用以下技术&#xff1a; Spring Boot&#xff1a;作为后端框架&#xff0c;用来提供数据接口。Thymeleaf&#xff1a;作为前端模板引擎&#xff0c;呈现网页。Leaflet…

Java律师法律咨询小程序

技术&#xff1a;Java、Springboot、mybatis、Vue、Mysql、微信小程序 1.代码干净整洁&#xff0c;可以快速二次开发和添加新功能 2.亮点可以添加AI法律咨询作为 创新点 系统分&#xff1a;用户小程序端&#xff0c;律师web端和管理员端 用户可以在小程序端登录系统进入首…

c++249多态

#include<iostream> using namespace std; class Parent { public:Parent(int a){this->a a;cout << " Parent" << a << endl;} public:virtual void print()//在子类里面可写可不写 {cout << "Parent" <<a<&l…