HarmonyOS鸿蒙Next中移动中的组件如何添加点击事件

HarmonyOS鸿蒙Next中移动中的组件如何添加点击事件

MatchComponent({ bean: this.threeBean })
  .position({ x: (this.screenWidth * 0.5) / 2 - this.threeBean.tabWidth / 2, y: this.screenHeight + this.threeBean.tabHeight })
  .translate({ y: this.threeBean.translateY })
  .onAreaChange((oldValue, newValue) => {
    if (this.threeBean) {
      this.threeBean.tabWidth = Number(newValue.width);
      this.threeBean.tabHeight = Number(newValue.height);
    }
  })
  .onAppear(() => {
    if (this.threeBean) {
      const translateY = -(this.screenHeight + this.threeBean.tabHeight + this.threeBean.tabHeight + immersionBar.getStatusBarHeight())
      this.getUIContext()?.animateTo({
        duration: 7000,
        delay: 3000,
        curve: Curve.Linear,
        iterations: 1,
        playMode: PlayMode.Normal
      }, () => {
        if (this.threeBean) {
          this.threeBean.translateY = translateY
        }
      })
    }
  })

更多关于HarmonyOS鸿蒙Next中移动中的组件如何添加点击事件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

9 回复

开发者你好,请问你这边是需要给自定义组件增加点击事件吗?

该场景可以将点击事件通过组件参数传入,避免直接在组件实例上设置onClick。将事件逻辑放到组件内部。如不满足请反馈。

@Component
export struct HcSearchBox {
  boxWidth: Length = 100
  boxHeight: number = 32
  ph: ResourceStr = '搜索题目'
  layoutWeightValue: number = 1
  clickFunction: () => void = () => {
    console.info("点击了,但未绑定回调");
  }

  build() {
    Row({ space: 4 }) {
      Image($r('app.media.startIcon'))
        .width(14)
        .aspectRatio(1)
        .fillColor(Color.Blue)
      Text(this.ph)
        .fontSize(14)
        .fontColor(Color.Pink)
    }
    .width(this.boxWidth)
    .height(this.boxHeight)
    .backgroundColor(Color.Blue)
    .borderRadius(this.boxHeight / 2)
    .justifyContent(FlexAlign.Center)
    .layoutWeight(this.layoutWeightValue)
    .onClick(() => {
      this.clickFunction();
    })
  }
}
import { HcSearchBox } from './HcSearchBox'

@Entry
@Component
struct Index {

  onSearchClick = () => {
    this.getUIContext().getPromptAction().showToast({message:'已设置回调'})
  }

  build() {
    Column() {
      HcSearchBox()
      HcSearchBox({
        clickFunction: this.onSearchClick
      })
    }
    .width(300)
    .height(300)
  }
}

更多关于HarmonyOS鸿蒙Next中移动中的组件如何添加点击事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这个方式试过不太行,因为动画是处于移动中的状态 点击事件无法赋值

我通过使用gesture方法也不行

@Component
export struct HcSearchBox {
  boxWidth: Length = 100
  boxHeight: number = 32
  ph: ResourceStr = '搜索题目'
  layoutWeightValue: number = 1
  clickFunction: () => void = () => {
    console.info("点击了,但未绑定回调");
  }
  @State num:number = 10;

  build() {
    Row({ space: 4 }) {
      Image($r('app.media.startIcon'))
        .width(14)
        .aspectRatio(1)
        .fillColor(Color.Blue)
      Text(this.ph)
        .fontSize(14)
        .fontColor(Color.Pink)
    }
    .width(this.boxWidth)
    .height(this.boxHeight)
    .backgroundColor(Color.Blue)
    .borderRadius(this.boxHeight / 2)
    .justifyContent(FlexAlign.Center)
    .layoutWeight(this.layoutWeightValue)
    .onClick(() => {
      this.clickFunction();
      this.num === 10 ? this.num = 50 : this.num = 10;
      console.log("=====>"+this.num);
    })
    .translate({x: this.num, y: this.num, z: this.num})
    .animation({
      duration: 2000,
      curve: Curve.EaseOut,
      iterations: 1,
      playMode: PlayMode.Normal
    })
  }
}

修改提供的示例中HcSearchBox组件代码, 增加translate和animation动画, 可以在点击时设置动画, 在组件移动过程中, 点击组件会再次执行另外一个动画, 可以在移动中给组件赋值调整属性动画.

麻烦看下上述方案是否可行, 如果不满足请详细描述你这边的问题场景.

结合动画控制手势拦截机制尝试一下。

直接使用onClick方法不行吗

不太行

在HarmonyOS Next中,为移动中的组件添加点击事件,可通过ArkUI的通用事件处理实现。使用onClick事件绑定到组件,即使组件处于动画或移动状态,点击事件仍会触发。需确保事件绑定在组件本身,而非其容器。示例代码片段如下:

@Component
struct MovingComponent {
  build() {
    Button('点击我')
      .onClick(() => {
        // 处理点击逻辑
      })
      .animation(/* 动画参数 */)
  }
}

事件响应与组件位置实时同步。

在HarmonyOS Next中,为移动中的组件添加点击事件,关键在于理解其声明式UI框架和手势处理机制。从你的代码看,组件正在执行动画(translateanimateTo),直接添加 .onClick 可能会因为动画过程中的坐标变换而导致事件响应不稳定或不符合预期。

更可靠的方法是使用手势事件,它专为处理复杂的交互而设计。你可以为 MatchComponent 添加一个 .gesture 修饰器,并在其中使用 TapGesture 来监听点击。这个手势系统能够更好地与动画状态协同工作。

以下是修改后的代码示例,展示了如何添加点击事件:

MatchComponent({ bean: this.threeBean })
  .position({ x: (this.screenWidth * 0.5) / 2 - this.threeBean.tabWidth / 2, y: this.screenHeight + this.threeBean.tabHeight })
  .translate({ y: this.threeBean.translateY })
  .gesture(
    TapGesture()
      .onAction(() => {
        // 在这里处理点击事件逻辑
        console.log('移动中的组件被点击了');
        // 例如,可以在这里访问或修改 this.threeBean 的属性
      })
  )
  .onAreaChange((oldValue, newValue) => {
    if (this.threeBean) {
      this.threeBean.tabWidth = Number(newValue.width);
      this.threeBean.tabHeight = Number(newValue.height);
    }
  })
  .onAppear(() => {
    // ... 原有的动画逻辑保持不变
  })

核心要点:

  1. 使用 .gesture(TapGesture()) 替代 .onClick:这是HarmonyOS Next中处理点击的标准方式,尤其适用于动态组件。它提供了更丰富的手势控制选项。
  2. 事件触发TapGestureonAction 回调会在用户完成一次点击(手指按下并抬起)时触发,与组件是否在运动无关。
  3. 性能与响应:手势系统经过优化,即使在动画过程中,也能有效识别交互意图,确保事件被正确派发到目标组件。

如果你的点击逻辑需要根据组件当前位置做出不同响应,可以在 onAction 回调中访问组件当前的状态(如 this.threeBean.translateY)进行计算。这种方式确保了事件处理与组件的渲染状态同步。

回到顶部