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

Flutter如何实现与参考图样式完全一致的Custom Tab bar

Flutter 自定义胶囊TabBar实现

你可以直接用下面的方案实现和参考图完全一致的效果,不需要引入第三方依赖:

自定义TabBar参考样式

核心实现逻辑

不要直接修改默认TabBar的外观参数硬凑样式,外层套容器做基底、单独控制指示器样式的方式可控性最高,要对齐的核心视觉点:

  • 外层是全圆角浅灰色胶囊容器,内边距4px
  • 选中项是白色圆角块,带极淡的投影,和外层灰底留均匀缝隙
  • 选中项文字加粗黑色,未选中项常规字重灰色
  • 切换时带默认平滑滑动动画,和TabBarView滑动联动

可直接运行的完整代码

import 'package:flutter/material.dart';

class CustomTabBarPage extends StatefulWidget {
  const CustomTabBarPage({super.key});

  @override
  State<CustomTabBarPage> createState() => _CustomTabBarPageState();
}

class _CustomTabBarPageState extends State<CustomTabBarPage> with SingleTickerProviderStateMixin {
  late final TabController _tabController;
  final List<String> _tabList = ['Bookings', 'Transactions'];

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            // TabBar 区域
            Container(
              margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
              padding: const EdgeInsets.all(4),
              height: 48,
              decoration: BoxDecoration(
                color: const Color(0xFFF2F3F5),
                borderRadius: BorderRadius.circular(24),
              ),
              child: TabBar(
                controller: _tabController,
                indicator: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(20),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.04),
                      blurRadius: 3,
                      offset: const Offset(0, 1),
                    )
                  ],
                ),
                indicatorSize: TabBarIndicatorSize.tab,
                labelColor: Colors.black,
                unselectedLabelColor: const Color(0xFF8A9099),
                labelStyle: const TextStyle(
                  fontSize: 15,
                  fontWeight: FontWeight.w600,
                ),
                unselectedLabelStyle: const TextStyle(
                  fontSize: 15,
                  fontWeight: FontWeight.w400,
                ),
                splashFactory: NoSplash.splashFactory,
                overlayColor: MaterialStateProperty.all(Colors.transparent),
                tabs: _tabList.map((item) => Tab(text: item)).toList(),
              ),
            ),
            // 内容区域
            Expanded(
              child: TabBarView(
                controller: _tabController,
                children: const [
                  Center(child: Text('Bookings 页面内容')),
                  Center(child: Text('Transactions 页面内容')),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

容易踩坑的调整点

  • 不要给TabBar本身设置背景色,背景色要设在外层Container上,否则指示器和背景之间不会有留白缝隙
  • 外层容器圆角设24,内部指示器圆角设20,刚好匹配4px内边距的圆角差,不会出现边缘错位
  • 关掉TabBar默认的水波纹和高亮效果,和参考图的交互视觉保持一致
  • 如果需要增减Tab项,只需要修改_tabList的内容即可,布局和动画会自动适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:27:23