HarmonyOS 5.0.0 或以上:实现按钮按压反馈与波纹点击动效


一、功能简介

本篇将实现一种模拟按钮点击波纹效果(Ripple)按压缩放反馈的微动效,用于提升用户操作的触觉反馈感知,适用于浮动按钮、确认操作、工具栏图标等 UI 元素。


二、技术能力点

功能点实现方式
按压反馈.scale() + @Gesture
波纹动效Overlay + Blank() 动画扩散圆
可复用封装自定义 RippleButton 组件

三、项目结构

entry/
├── src/main/ets/components/RippleButton.ets
├── src/main/ets/pages/RippleEffectDemo.ets

四、组件封装(RippleButton.ets)

@Component
export default struct RippleButton {
  @Prop text: string
  @Prop onClick: () => void

  @State pressed: boolean = false
  @State rippleVisible: boolean = false
  @State rippleScale: number = 0

  build() {
    Stack() {
      Button(this.text)
        .scale({ x: this.pressed ? 0.96 : 1, y: this.pressed ? 0.96 : 1 })
        .backgroundColor('#ffffff')
        .borderRadius(12)
        .padding(14)
        .shadow({ radius: 4, color: '#999' })
        .onClick(() => this.onClick())
        .gesture(
          TapGesture()
            .onActionStart(() => {
              this.pressed = true
              this.rippleVisible = true
              this.rippleScale = 0
              setTimeout(() => this.rippleScale = 2.5, 10)
            })
            .onActionEnd(() => {
              this.pressed = false
              setTimeout(() => this.rippleVisible = false, 300)
            })
        )

      If(this.rippleVisible, () => {
        Blank()
          .position({ x: 0, y: 0 })
          .backgroundColor('#cccccc40')
          .borderRadius(1000)
          .scale({ x: this.rippleScale, y: this.rippleScale })
          .opacity(1 - this.rippleScale / 3)
          .size({ width: 50, height: 50 })
          .align(Alignment.Center)
          .animate({
            duration: 300,
            curve: Curve.EaseOut
          })
      })
    }
    .width('100%')
    .height(60)
  }
}

五、使用示例页面(RippleEffectDemo.ets)

import RippleButton from '../components/RippleButton'

@Entry
@Component
struct RippleEffectDemo {
  @State msg: string = ''

  build() {
    Column() {
      Text('HarmonyOS 5.0.0 或以上')
        .fontSize(20)
        .margin({ bottom: 16 })

      RippleButton({
        text: '📥 点击我',
        onClick: () => this.msg = `已点击 @ ${new Date().toLocaleTimeString()}`
      })

      Text(this.msg)
        .fontSize(14)
        .margin({ top: 20 })
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#f5f5f5')
  }
}

六、运行效果

  • 按钮按下时缩小轻微反馈

  • 同时显示中心扩散波纹(淡灰圆圈);

  • 动效持续约 300ms 后自动消失;

  • 可复用组件支持任意按钮文案与回调事件。


七、常见问题与优化建议

问题原因解决方案
波纹不在中心未使用 .align(Alignment.Center)确保波纹居中渲染
ripple 不消失没有定时关闭setTimeout() 控制销毁时机
动效不平滑缺少 .animate()添加缓动曲线如 Curve.EaseOut 提升表现

八、拓展建议

  • 将波纹色改为主题色或自定义传参;

  • 添加图标/按钮变体(如圆形 FAB);

  • 支持 longPress 波纹变色;

  • 可组合进按钮组、操作菜单中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值