HarmonyOS 鸿蒙Next 应用内浮窗点击事件相关

发布于 1周前 作者 eggper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 应用内浮窗点击事件相关 问题:
自定义浮窗在展示时,通过
getUIContext().showAlertDialog(
{
title: ‘’,
message: ‘’,
autoCancel: true,
alignment: DialogAlignment.Bottom,
})
实现了背景半透明,但是这个dialog无法被主动关闭,自定义浮窗上有关闭按钮,点击以后,下层的Dialog还在。

3 回复

请使用getPromptAction可主动控制关闭:

import window from '@ohos.window';
import { BusinessError } from '@kit.BasicServicesKit';
import animator, { AnimatorOptions, AnimatorResult } from '@ohos.animator';

class FloatPosition {
  x: number = 0;
  y: number = 0;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

@Entry
@Component
struct FloatContent {
  private floatWindow: window.Window = window.findWindow("floatWindow");
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
  @State @Watch("onMoveWindow") private windowPosition: FloatPosition = this.initPosition();
  
  @State state: AnimationStatus = AnimationStatus.Running;
  @State more: boolean = false;
  @State windowStage: window.WindowStage = AppStorage.get("windowStage") as window.WindowStage;

  private customDialogComponentId: number = 0;

  initPosition() {
    this.floatWindow.moveWindowTo(0, 100);
    return new FloatPosition(0, 100);
  }

  onMoveWindow() {
    this.floatWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
  }

  aboutToAppear() {
    const context = getContext(this);
    context.eventHub.on('update', () => {});
    context.eventHub.on('touchOutside', () => {
      this.more = false;
    });
  }

  aboutToDisappear(): void {
    const context = getContext(this);
    context.eventHub.off('update');
    context.eventHub.off('touchOutside');
  }

  @Builder
  customDialogComponent() {
    Column() {
      Text('弹窗').fontSize(30);
      Row({ space: 50 }) {
        Button("确认").onClick(() => {
          this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId);
        });
        Button("取消").onClick(() => {
          this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId);
        });
      }
    }.height(200).padding(5).justifyContent(FlexAlign.SpaceBetween);
  }

  build() {
    Row() {
      this.contentLayout();
    }
    .width('100%')
    .height('100%')
    .borderRadius(20)
    .onClick(() => {
      this.windowStage.getMainWindowSync().getUIContext().getPromptAction().openCustomDialog({
        builder: () => {
          this.customDialogComponent();
        },
        onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
          console.info("reason" + JSON.stringify(dismissDialogAction.reason));
          console.log("dialog onWillDismiss");
          if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
            dismissDialogAction.dismiss();
          }
          if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
            dismissDialogAction.dismiss();
          }
        }
      }).then((dialogId: number) => {
        this.customDialogComponentId = dialogId;
      });
      this.more = true;
    })
    .gesture(
      PanGesture(this.panOption)
        .onActionStart((event: GestureEvent) => {})
        .onActionUpdate((event: GestureEvent) => {
          this.windowPosition.x += event.offsetX;
          this.windowPosition.y += event.offsetY;
        })
        .onActionEnd(() => {
          let animatorResult: AnimatorResult = animator.create({
            duration: 220,
            easing: "ease-in",
            delay: 0,
            fill: "forwards",
            direction: "normal",
            iterations: 1,
            begin: this.windowPosition.x,
            end: 0
          });
          animatorResult.onFrame = (value: number) => {
            this.windowPosition.x = value;
          };
          animatorResult.play();
        })
    )
    .backgroundColor("#fff32121");
  }

  @Builder
  contentLayout() {
    ImageAnimator()
      .images([
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
      ])
      .width(30)
      .height(30)
      .duration(1000)
      .state(this.state)
      .fillMode(FillMode.None)
      .iterations(-1);

    if (this.more) {
      Text("点击关闭")
        .fontSize(20)
        .onClick(()=>{
          window.findWindow("floatWindow").destroyWindow();
          this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId);
        });
    }
  }
  • 以上是初步分析结论,如有疑问可以展开回复,看到后会继续协助定位阻碍点。
  • 开源网站上收录了UI、系统接口、Web、创新特性等场景化鸿蒙示例DEMO,开发中可以参考:https://gitee.com/scenario-samples/demo-index

更多关于HarmonyOS 鸿蒙Next 应用内浮窗点击事件相关的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用getPromptAction可主动控制关闭:

import window from '@ohos.window';
import { BusinessError } from '@kit.BasicServicesKit';
import animator, { AnimatorOptions, AnimatorResult } from '@ohos.animator';

class FloatPosition {
  x: number = 0
  y: number = 0

  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
}

/**
 * @author gq
 * @date
 * @des
 */
@Entry
@Component
struct FloatContent {
  /**
   * 位置相关
   */
  private floatWindow: window.Window = window.findWindow("floatWindow")
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
  @State @Watch("onMoveWindow") private windowPosition: FloatPosition = this.initPosition()
  /**
   * 内容相关
   */
  @State state: AnimationStatus = AnimationStatus.Running
  @State more: boolean = false
  @State windowStage: window.WindowStage = AppStorage.get("windowStage") as window.WindowStage;
  private customDialogComponentId: number = 0
  initPosition() {
    this.floatWindow.moveWindowTo(0, 100)
    return new FloatPosition(0, 100)
  }

  onMoveWindow() {
    this.floatWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
  }

  aboutToAppear() {
    const context = getContext(this)
    context.eventHub.on('update', () => {
    })
    context.eventHub.on('touchOutside', () => {
      this.more = false
    })
  }

  aboutToDisappear(): void {
    const context = getContext(this)
    context.eventHub.off('update')
    context.eventHub.off('touchOutside')
  }
  @Builder
    customDialogComponent() {
  Column() {
    Text('弹窗').fontSize(30)
    Row({ space: 50 }) {
      Button("确认").onClick(() => {
        this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId)
      })
      Button("取消").onClick(() => {
        this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId)
      })
    }
  }.height(200).padding(5).justifyContent(FlexAlign.SpaceBetween)
}

  build() {
    Row() {
      this.contentLayout()
    }
    .width('100%')
    .height('100%')
    .borderRadius(20)
    .onClick(() => {

      this.windowStage.getMainWindowSync().getUIContext().getPromptAction().openCustomDialog(
        {
          builder: () => {
            this.customDialogComponent()
          },
          onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
            console.info("reason" + JSON.stringify(dismissDialogAction.reason))
            console.log("dialog onWillDismiss")
            if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
              dismissDialogAction.dismiss()
            }
            if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
              dismissDialogAction.dismiss()
            }
          }
        }).then((dialogId: number) => {
        this.customDialogComponentId = dialogId
        }
      )
      this.more = true
    })
    .gesture(
      PanGesture(this.panOption)
        .onActionStart((event: GestureEvent) => {
        })
        .onActionUpdate((event: GestureEvent) => {
          this.windowPosition.x += event.offsetX;
          this.windowPosition.y += event.offsetY;
        })
        .onActionEnd(() => {
          let animatorResult: AnimatorResult = animator.create({
            duration: 220,
            easing: "ease-in",
            delay: 0,
            fill: "forwards",
            direction: "normal",
            iterations: 1,
            begin: this.windowPosition.x,
            end: 0
          })
          animatorResult.onFrame = (value: number) => {
            this.windowPosition.x = value
          }
          animatorResult.play()
        })
    )
    .backgroundColor("#fff32121")
  }

  @Builder
  contentLayout() {
    ImageAnimator()
      .images([
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
        { src: $r('app.media.1') },
      ])
      .width(30)
      .height(30)
      .duration(1000)
      .state(this.state)
      .fillMode(FillMode.None)
      .iterations(-1)

    if (this.more) {
      Text("点击关闭")
        .fontSize(20)
        .onClick(()=>{
          window.findWindow("floatWindow").destroyWindow()
          this.windowStage.getMainWindowSync().getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId)
        })
    }
  }
}

针对帖子标题“HarmonyOS 鸿蒙Next 应用内浮窗点击事件相关”的问题,以下是一个简洁的专业回答:

在HarmonyOS鸿蒙Next系统中,处理应用内浮窗的点击事件通常涉及使用ArkUI框架(包含eTS和JS两种开发语言)。对于浮窗组件的点击事件处理,你需要确保浮窗视图(如Container、Button等组件)已经正确添加到窗口中,并且已经绑定了相应的事件监听器。

具体来说,你可以通过以下步骤来实现点击事件的处理:

  1. 定义浮窗组件:在ArkUI中,使用相应的组件(如Button)来创建浮窗视图。

  2. 绑定点击事件:通过组件的.onClick()方法或其他事件绑定机制,为浮窗组件绑定点击事件处理函数。

  3. 实现事件处理函数:在事件处理函数中编写逻辑,以响应点击事件,如显示提示信息、改变界面状态等。

请注意,浮窗权限和显示策略可能受到系统策略的限制,确保你的应用已经获得了相应的权限,并且遵循了系统的浮窗显示规则。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部