一、功能简介
本篇将实现一种模拟按钮点击波纹效果(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
波纹变色; -
可组合进按钮组、操作菜单中。