TabBar(
controller: _tabController,
unselectedLabelColor: Colors.grey,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(
16.0,
),
color: colors[_tabController.index],
),
tabs: const [
Tab(text: "INFO"),
Tab(text: "ENGAGEMENT"),
Tab(text: "TRACK"),
],
labelStyle: const TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w600),
unselectedLabelStyle: const TextStyle(
color: Colors.grey,
fontSize: 13,
fontWeight: FontWeight.w600),
),
),
),
I wanted Each Tab to have a Different color when they're selected So I tried to change the color when the index changes by storing them in a list But it doesnt work without setState (I know its not changing the state because the color changes after quick reload)
This is the expected output
CodePudding user response:
You can include a listener on TabController
and call setState
there.
_tabController = TabController(vsync: this, length: myTabs.length)
..addListener(() {
setState(() {});
});
CodePudding user response:
The code below should do the trick. Check out the screen recording and the
And here's the code itself as a minimal-reproducible-example:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late TabController tabController;
int _tabIndex = 0;
@override
void initState() {
super.initState();
tabController = TabController(length: 3, vsync: this)
..addListener(() {
setState(() => _tabIndex = tabController.index);
});
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Container(
height: 48,
margin: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(20)),
border: Border.all(width: 2),
),
child: TabBar(
indicatorWeight: 0,
controller: tabController,
indicator: const BoxDecoration(),
unselectedLabelColor: Colors.black26,
labelPadding: const EdgeInsets.all(2),
splashBorderRadius: BorderRadius.circular(20),
tabs: [
Container(
decoration: BoxDecoration(
color: _tabIndex == 0
? const Color(0xFF64c636)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: const Center(child: Text('INFO')),
),
Container(
decoration: BoxDecoration(
color: _tabIndex == 1
? const Color(0xFFf2c32c)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: const Center(child: Text('ENGAGEMENT')),
),
Container(
decoration: BoxDecoration(
color: _tabIndex == 2
? const Color(0xFF00a9ce)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: const Center(child: Text('TRACK')),
),
],
),
),
);
}
}