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

Flutter实现Scaffold体内带圆形指示器的自定义TabBar

Flutter 自定义TabBar实现圆形底部指示器(置于Scaffold body区域)

以下是实现需求的完整可运行代码,激活的Tab标题下方会显示圆形指示器,且TabBar放置在Scaffold的body区域:

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(
      title: 'Custom TabBar Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const CustomTabBarScreen(),
    );
  }
}

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

  @override
  State<CustomTabBarScreen> createState() => _CustomTabBarScreenState();
}

class _CustomTabBarScreenState extends State<CustomTabBarScreen> {
  final List<String> _tabTitles = ['Tab 1', 'Tab 2', 'Tab 3', 'Tab 4'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Custom TabBar')),
      body: Column(
        children: [
          // 置于body区域的TabBar
          DefaultTabController(
            length: _tabTitles.length,
            child: TabBar(
              indicator: const CircleTabIndicator(color: Colors.blue, radius: 4),
              labelColor: Colors.blue,
              unselectedLabelColor: Colors.grey,
              tabs: _tabTitles.map((title) => Tab(text: title)).toList(),
            ),
          ),
          // 对应Tab的内容区域
          Expanded(
            child: DefaultTabController(
              length: _tabTitles.length,
              child: TabBarView(
                children: _tabTitles.map((title) {
                  return Center(child: Text('Content for $title'));
                }).toList(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// 自定义圆形指示器
class CircleTabIndicator extends Decoration {
  final Color color;
  final double radius;

  const CircleTabIndicator({required this.color, required this.radius});

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    return _CirclePainter(color: color, radius: radius);
  }
}

class _CirclePainter extends BoxPainter {
  final Color color;
  final double radius;

  _CirclePainter({required this.color, required this.radius});

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    final Paint paint = Paint()..color = color;
    final Offset circleOffset = Offset(
      configuration.size!.width / 2 + offset.dx,
      configuration.size!.height - radius + offset.dy,
    );
    canvas.drawCircle(circleOffset, radius, paint);
  }
}

关键细节说明:

  • 自定义圆形指示器:通过继承Decoration实现CircleTabIndicator,利用Canvas绘制圆形,精准定位在Tab标题底部中心位置。
  • TabBar布局:将TabBar放在Column组件中,配合Expanded包裹的TabBarView,实现TabBar置于body区域的布局结构。
  • 样式可定制:可修改CircleTabIndicator的color和radius调整指示器的颜色与大小;通过TabBar的labelColor、unselectedLabelColor控制标题文字的选中/未选中状态颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:37:40