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

Flutter如何实现带TabBar与TabBarView的带动画Bottom Sheet

实现思路

你当前的写法逻辑和要实现的效果方向不一致:你现在把TabBarView放在了Scaffold的body区域,切换Tab会直接替换整个页面内容,而参考效果里的Tab是固定在底部,点击后弹出对应高度的Bottom Sheet,不会替换页面主体内容。具体实现逻辑可以参考这几点:

  • 先把Scaffold的body替换为你的App主业务内容,移除原来body里的TabBarView结构
  • 不要直接使用Scaffold自带的bottomSheet属性,这个属性默认没有动态高度动画能力,你可以选择自定义可持久化Bottom Sheet,或者用模态Bottom Sheet组件承载Tab结构
  • 把TabBar和TabBarView都放到Bottom Sheet的内容容器里,用AnimatedSize或者AnimatedContainer包裹TabBarView,开启动画属性
  • 给每个Tab对应的页面组件绑定GlobalKey,Tab切换时获取当前页面的渲染高度,传给动画控制器,驱动Bottom Sheet的高度平滑过渡,动画时长和曲线可以自己调整匹配参考效果
可用的第三方包

不用完全手搓动画逻辑,有成熟的第三方包可以直接适配这个场景:

  • 优先选sliding_up_panel:本身就是专门做可滑动底部面板的组件,支持自定义内部结构,自带高度变化动画,你只需要把TabBar+TabBarView放到面板内容里,开启动态尺寸动画的参数,就能实现Tab切换时的高度自动过渡效果,不需要自己手动计算每个页面的高度,适配成本很低。
  • 也可以用custom_bottom_sheet:对原生Bottom Sheet做了扩展,支持动态修改内容高度、自定义动画参数,对Tab场景的适配性也很好。
简化实现示例

这里给你一个基于sliding_up_panel的核心代码参考:

class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final PanelController _panelController = PanelController();

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 4, vsync: this, initialIndex: 2);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 这里放你的APP主页面内容
      body: const SafeArea(child: Center(child: Text("APP主内容"))),
      body: SlidingUpPanel(
        controller: _panelController,
        minHeight: 60, // 最小高度设置为TabBar的高度
        maxHeight: MediaQuery.of(context).size.height * 0.8, // 最大高度可根据需求调整
        animatePanelSize: true, // 开启动态高度动画
        panel: Column(
          children: [
            // 固定的TabBar
            TabBar(
              controller: _tabController,
              labelColor: Colors.blue,
              indicatorColor: Colors.black,
              unselectedLabelColor: Colors.black,
              tabs: const [
                Tab(icon: Icon(Icons.home_outlined)),
                Tab(icon: Icon(Icons.shopping_cart_outlined)),
                Tab(icon: Icon(Icons.favorite_border)),
                Tab(icon: Icon(Icons.send)),
              ],
            ),
            // 动态高度的Tab内容区域
            Expanded(
              child: TabBarView(
                controller: _tabController,
                children: const [
                  HomePage(),
                  PersonalData(),
                  LoginPage(),
                  RegistrationPage()
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:15:07