如何创建可点击的Neumorphism拟态按钮并实现按压动画?
Flutter拟态按钮实现按压动画效果
要实现拟态按钮的按压动画,你可以通过AnimatedContainer结合GestureDetector来模拟真实的按压反馈——按压时反转内外阴影方向、轻微下移按钮,松开后恢复原状,效果和原生ElevatedButton一致。
以下是完整的实现代码:
import 'package:flutter/material.dart'; class NeumorphicButton extends StatefulWidget { final String text; final VoidCallback onPressed; const NeumorphicButton({ super.key, required this.text, required this.onPressed, }); @override State<NeumorphicButton> createState() => _NeumorphicButtonState(); } class _NeumorphicButtonState extends State<NeumorphicButton> { bool _isPressed = false; @override Widget build(BuildContext context) { return GestureDetector( onTapDown: (_) => setState(() => _isPressed = true), onTapUp: (_) { setState(() => _isPressed = false); widget.onPressed(); }, onTapCancel: () => setState(() => _isPressed = false), child: AnimatedContainer( duration: const Duration(milliseconds: 150), width: 200, height: 50, transform: _isPressed ? Matrix4.translateValues(0, 5, 0) : Matrix4.identity(), decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(30), boxShadow: _isPressed ? [ // 按压时反转阴影:内凹效果 BoxShadow( color: Colors.grey[400]!, blurRadius: 20, offset: const Offset(0, -10), ), BoxShadow( color: Colors.white, blurRadius: 20, offset: const Offset(0, 10), ), ] : [ // 默认状态外阴影 BoxShadow( color: Colors.grey[400]!, blurRadius: 20, offset: const Offset(0, 10), ), BoxShadow( color: Colors.white, blurRadius: 20, offset: const Offset(0, -10), ), ], ), child: Center( child: Text( widget.text, style: TextStyle( color: Colors.grey[600], fontSize: 16, fontWeight: FontWeight.w500, ), ), ), ), ); } } // 使用示例 // NeumorphicButton( // text: 'Button', // onPressed: () { // // 自定义点击逻辑 // print('按钮被触发'); // }, // )
关键实现点说明:
- 状态跟踪:用
_isPressed变量记录按钮按压状态,通过setState触发UI更新。 - 平滑动画:
AnimatedContainer自动处理属性变化的过渡动画,150ms的时长和原生按钮动画速度匹配。 - 按压反馈:
- 阴影反转:按压时交换深色/白色阴影的偏移方向,模拟按钮内凹的视觉效果。
- 位置下移:通过
Matrix4.translateValues让按钮轻微下移5px,强化按压的物理感。
- 事件处理:
GestureDetector的onTapDown/onTapUp/onTapCancel分别处理按压开始、结束和取消场景,确保动画在任何情况下都能正确恢复。
这样实现的拟态按钮,既保留了你需要的拟态外观,又能提供和原生按钮一致的按压交互体验。
内容的提问来源于stack exchange,提问作者Pannam
相关产品推荐
相关产品推荐

