如何在Flutter中实现如图所示点击可放大的垂直条组件?
实现可交互垂直条效果的Flutter代码方案
以下是完整可运行的实现代码,已经内置点击放大回弹的交互效果,同时支持自定义点击回调:
import 'package:flutter/material.dart'; class InteractiveVerticalBar extends StatefulWidget { // 外部传入的点击回调 final VoidCallback? onPressed; // 垂直条基础高度 final double baseHeight; // 垂直条宽度 final double barWidth; // 垂直条颜色 final Color barColor; // 点击后的最大缩放比例 final double maxScale; const InteractiveVerticalBar({ super.key, this.onPressed, this.baseHeight = 80, this.barWidth = 12, this.barColor = Colors.blueAccent, this.maxScale = 1.3, }); @override State<InteractiveVerticalBar> createState() => _InteractiveVerticalBarState(); } class _InteractiveVerticalBarState extends State<InteractiveVerticalBar> with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation<double> _scaleAnimation; @override void initState() { super.initState(); // 初始化动画控制器,200ms的时长符合移动端点击反馈的常规体验 _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 200), ); // 定义缩放动画曲线,使用easeInOut实现平滑的放大回弹效果 _scaleAnimation = Tween<double>(begin: 1.0, end: widget.maxScale).animate( CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, ), ); // 动画播放完成后自动复位到初始大小 _animationController.addStatusListener((status) { if (status == AnimationStatus.completed) { _animationController.reverse(); } }); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () { // 触发缩放动画 _animationController.forward(from: 0); // 执行外部传入的点击回调 widget.onPressed?.call(); }, child: AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) { return Transform.scale( // 仅沿Y轴缩放,实现垂直方向放大的效果 scaleY: _scaleAnimation.value, // 缩放锚点设为底部,符合垂直条跳动的视觉逻辑 alignment: Alignment.bottomCenter, child: Container( width: widget.barWidth, height: widget.baseHeight, decoration: BoxDecoration( color: widget.barColor, borderRadius: BorderRadius.circular(widget.barWidth / 2), ), ), ); }, ), ); } } // 调用示例 void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ // 可以排列多个垂直条实现频谱效果 InteractiveVerticalBar( baseHeight: 60, onPressed: () => print("第一个垂直条被点击"), ), const SizedBox(width: 8), InteractiveVerticalBar( baseHeight: 90, barColor: Colors.green, onPressed: () => print("第二个垂直条被点击"), ), const SizedBox(width: 8), InteractiveVerticalBar( baseHeight: 75, barColor: Colors.orange, onPressed: () => print("第三个垂直条被点击"), ), ], ), ), ), ); } }
核心特性说明
- 点击垂直条时会自动先放大到设定的最大比例,之后平滑回弹到原始大小,符合需求的交互效果
- 所有样式参数支持自定义:高度、宽度、颜色、缩放比例都可以根据业务需求调整
- 如果需要实现多个条的自动跳动频谱效果,只需增加定时器随机修改每个条的
baseHeight即可
内容的提问来源于stack exchange,提问作者Bakhshish
相关产品推荐
相关产品推荐

