You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:35:20