在这里插入图片描述

📋 前言

活动主旨
以 “星光” 为引,为鸿蒙生态聚能!本次征文活动面向全体鸿蒙学习者、开发者及 2024/2025 HarmonyOS 创新赛参赛者,旨在搭建一个技术分享与成长交流的平台 —— 无论是你从入门到精通的鸿蒙学习心得、项目实战中的技术突破,还是鸿蒙相关项目的从 0 到 1 复盘,都能在这里找到共鸣与认可。
在这里插入图片描述
关于 HarmonyOS 应用开发者基础认证
通过系统化的课程学习,熟练掌握 DevEco Studio,ArkTS,ArkUI,预览器,模拟器,SDK 等 HarmonyOS 应用开发的关键概念,具备基础的应用开发能力。


🎯 项目介绍

在移动应用开发中,我们经常会遇到需要持续向用户展示动态数据、提供快速功能导航、支持多任务并行处理等场景。这时候,悬浮窗就成为了一个非常不错和高效的解决方案。接下来要介绍的项目,主要是通过子窗口实现全局悬浮窗效果,通过本题可以让我们初步了解子窗口的创建、定制、销毁。

接下来,我们可以通过一个实际案例,带大家深入了解如何在鸿蒙应用中实现全局悬浮窗效果。这个项目是我四月份那会参加广州站的鸿蒙 HDC 活动记录的实战项目,同时也是那天实操环节的项目,因此在这篇文章中给大家分析下这个项目以及实现方法。具体实现的效果如下图。
在这里插入图片描述
软件要求:
DevEco Studio 版本:DevEco Studio 5.0.0 Release 及以上。 HarmonyOS SDK 版本:HarmonyOS 5.0.0 Release SDK 及以上。

硬件要求:
华为⼿机、模拟器。(HarmonyOS 系统:HarmonyOS 5.0.0 Release 及以上)


🎯 实现过程

主要代码结构
在这里插入图片描述
在 EntryAbility.ets 中获取窗口管理器对象并使用 AppStorage 保存。
在这里插入图片描述

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    });
    AppStorage.setOrCreate("windowStage",windowStage)
  }

窗口管理 WindowUti l文件:负责窗口的创建、窗口样式配置等。如设置窗口长宽分别为 300px;窗口背景颜色为透明。
在这里插入图片描述
应用首页 index.ets:这边使用 Tabs() 组件简单实现多页面视图切换,并且在第一个页签内增加测试按钮。

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  private suw = new WindowUtil()
  build() {
    Tabs() {
      TabContent() {
        Column() {
          Text('首页的内容').fontSize(30)
          Button('开始下载任务').onClick(() => {
            this.suw.showSubWindow()
          })
        }
      }
      .tabBar('首页')

      TabContent() {
        page1()
      }
      .tabBar('发现')

      TabContent() {
        page2()
      }
      .tabBar('我的')
    }
  }
}

子窗口页面开发 SubWindow.ets:因为子窗口背景为透明,所以可以通过配置容器或组件样式实现个性化子窗口(该项目通过设置边框圆角实现圆形子窗口,也可以通过 Canvas 实现其形状)。并且通过 gesture 绑定滑动手势,实现窗口跟手效果。

import window from '@ohos.window';

interface Position {
  x: number,
  y: number
}

@Entry
@Component
struct SubWindow {
  @State message: string = '任务准备中';
  @State @Watch("moveWindow") windowPosition: Position = { x: 300, y: 300 };
  @State progress: number = 0;
  private floatWindow: window.Window = window.findWindow("mySubWindow")
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
  build() {
    Stack() {
      Row() {
        Column() {
          Text(this.message)
            .fontSize(15)
            .fontColor(Color.White)
          Progress({ value: 0, total: 100, type: ProgressType.Capsule })
            .width('80%')
            .height(10)
            .backgroundColor(Color.Green)
            .color(Color.White)
            .value(this.progress)
        }
        .justifyContent(FlexAlign.Center)
        .width('100%')
        .height('100%')
      }
      Row() {
        Image($r('app.media.close')).width('10vp').height('10vp').onClick(() => {
          this.floatWindow.destroyWindow()
        })
      }
      .justifyContent(FlexAlign.End)
      .alignItems(VerticalAlign.Top)
      .width('100%')
      .height('100%')
    }
    .borderRadius(50)
    .backgroundColor(Color.Green)
    .gesture(PanGesture(this.panOption).onActionUpdate((event: GestureEvent) => {
      this.windowPosition.x += event.offsetX;
      this.windowPosition.y += event.offsetY;
    })
    )
  }
  aboutToAppear(): void {
    setTimeout(() => {
      const intervalID = setInterval(() => {
        if (this.progress <= 100) {
          this.message = '处理中'
          this.progress += 1;
        } else {
          this.message = "任务完成"
          clearInterval(intervalID)
        }
      }, 50)
    }, 2000)
  }
  moveWindow(changedPropertyName: string) {
    this.floatWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
  }
}

实现效果如下
在这里插入图片描述
在这里插入图片描述


📝最后

以上就是下载功能按钮与全局悬浮窗联动实战开发的全部内容了,通过本次实战开发,可以深入掌握了应用内全局悬浮窗的实现方案。从窗口管理器的初始化、子窗口的创建与样式配置,到悬浮窗页面的手势交互和进度展示,完整构建了一个可拖拽的圆形悬浮窗组件。

在实际开发中,悬浮窗的使用需要兼顾功能性和用户体验。我们既要注意避免悬浮窗干扰用户正常操作,提供便捷的关闭入口,也要关注性能优化,减少不必要的内存占用。本次实现的悬浮窗支持自由拖拽、进度实时更新和一键关闭,这些特性确保了功能实用性的同时,也体现了对用户体验的细致考量。
在这里插入图片描述

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐