Flutter中点击Floating Action Button实现底部弹出面板的方法
Flutter实现点击FAB弹出/收起底部面板
你要的这种从底部滑入、顶部滑出的面板,可通过动画控制器+滑动过渡组件结合状态管理实现,以下是完整可运行代码:
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const BottomPanelDemo(), theme: ThemeData(primarySwatch: Colors.blue), ); } } class BottomPanelDemo extends StatefulWidget { const BottomPanelDemo({super.key}); @override State<BottomPanelDemo> createState() => _BottomPanelDemoState(); } class _BottomPanelDemoState extends State<BottomPanelDemo> with SingleTickerProviderStateMixin { bool isPanelVisible = false; late AnimationController _animationController; late Animation<Offset> _slideAnimation; @override void initState() { super.initState(); // 初始化动画控制器,设置动画时长 _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300), ); // 定义滑动轨迹:从屏幕底部外滑入到屏幕内 _slideAnimation = Tween<Offset>( begin: const Offset(0, 1), end: const Offset(0, 0), ).animate(CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, )); } // 切换面板显示/隐藏状态 void _togglePanel() { setState(() { isPanelVisible = !isPanelVisible; }); isPanelVisible ? _animationController.forward() : _animationController.reverse(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("底部面板Demo")), floatingActionButton: FloatingActionButton( onPressed: _togglePanel, child: Icon(isPanelVisible ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_up), ), body: Stack( children: [ // 主页面内容 const Center(child: Text("主页面区域")), // 滑动过渡面板 SlideTransition( position: _slideAnimation, child: Container( height: MediaQuery.of(context).size.height * 0.4, // 面板高度占屏幕40% width: double.infinity, color: Colors.white, padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "面板标题", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), Expanded( child: ListView.builder( itemCount: 5, itemBuilder: (context, index) => ListTile(title: Text("选项 ${index+1}")), ), ), ], ), ), ), ], ), ); } }
关键说明:
- 用
AnimationController控制动画时长,SlideTransition实现面板的滑入滑出效果,Curves.easeInOut保证动画过渡自然 - 通过
isPanelVisible变量维护面板状态,点击FAB时切换状态并执行对应动画 - 面板高度可通过
height参数自定义,当前设置为屏幕高度的40% - FAB图标随面板状态切换,提升交互直观性
若需添加点击外部收起面板的功能,可在Stack中添加一层透明遮罩,点击遮罩时调用_togglePanel()方法。
内容的提问来源于stack exchange,提问作者Boatti
相关产品推荐
相关产品推荐

