103 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
class PillTabBar extends StatefulWidget {
final TabController controller;
final List<String> tabs;
final List<IconData> icons;
final Color selectedColor;
final Color unselectedColor;
final Color indicatorColor;
final double height;
final ValueChanged<int>? onTap;
const PillTabBar({
Key? key,
required this.controller,
required this.tabs,
required this.icons,
this.selectedColor = Colors.blue,
this.unselectedColor = Colors.grey,
this.indicatorColor = Colors.blueAccent,
this.height = 48,
this.onTap,
}) : super(key: key);
@override
State<PillTabBar> createState() => _PillTabBarState();
}
class _PillTabBarState extends State<PillTabBar> {
@override
void initState() {
super.initState();
widget.controller.addListener(_onTabChange);
}
void _onTabChange() {
if (mounted) setState(() {});
}
@override
void dispose() {
widget.controller.removeListener(_onTabChange);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Container(
height: widget.height,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(widget.height / 2),
),
child: TabBar(
controller: widget.controller,
isScrollable: true, // important for dynamic spacing
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
color: widget.indicatorColor.withOpacity(0.2),
borderRadius: BorderRadius.circular(widget.height / 2),
),
onTap: widget.onTap,
tabs: List.generate(widget.tabs.length, (index) {
final isSelected = widget.controller.index == index;
return AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: EdgeInsets.symmetric(
horizontal:
isSelected ? 12 : 6, // reduce padding for unselected tabs
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
widget.icons[index],
size: isSelected ? 18 : 16,
color: isSelected
? widget.selectedColor
: widget.unselectedColor,
),
if (isSelected) ...[
const SizedBox(width: 4),
Text(
widget.tabs[index],
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: widget.selectedColor,
),
),
],
],
),
);
}),
)),
);
}
}