@@ -2219,7 +2219,7 @@ class TabPageSelectorIndicator extends StatelessWidget {
2219
2219
///
2220
2220
/// If a [TabController] is not provided, then there must be a
2221
2221
/// [DefaultTabController] ancestor.
2222
- class TabPageSelector extends StatelessWidget {
2222
+ class TabPageSelector extends StatefulWidget {
2223
2223
/// Creates a compact widget that indicates which tab has been selected.
2224
2224
const TabPageSelector ({
2225
2225
super .key,
@@ -2256,6 +2256,67 @@ class TabPageSelector extends StatelessWidget {
2256
2256
/// Defaults to [BorderStyle.solid] if value is not specified.
2257
2257
final BorderStyle ? borderStyle;
2258
2258
2259
+ @override
2260
+ State <TabPageSelector > createState () => _TabPageSelectorState ();
2261
+ }
2262
+
2263
+ class _TabPageSelectorState extends State <TabPageSelector > {
2264
+ TabController ? _previousTabController;
2265
+ TabController get _tabController {
2266
+ final TabController ? tabController = widget.controller ?? DefaultTabController .maybeOf (context);
2267
+ assert (() {
2268
+ if (tabController == null ) {
2269
+ throw FlutterError (
2270
+ 'No TabController for $runtimeType .\n '
2271
+ 'When creating a $runtimeType , you must either provide an explicit TabController '
2272
+ 'using the "controller" property, or you must ensure that there is a '
2273
+ 'DefaultTabController above the $runtimeType .\n '
2274
+ 'In this case, there was neither an explicit controller nor a default controller.' ,
2275
+ );
2276
+ }
2277
+ return true ;
2278
+ }());
2279
+ return tabController! ;
2280
+ }
2281
+
2282
+ CurvedAnimation ? _animation;
2283
+
2284
+ @override
2285
+ void didUpdateWidget (TabPageSelector oldWidget) {
2286
+ super .didUpdateWidget (oldWidget);
2287
+ if (_previousTabController? .animation != _tabController.animation) {
2288
+ _setAnimation ();
2289
+ }
2290
+ if (_previousTabController != _tabController) {
2291
+ _previousTabController = _tabController;
2292
+ }
2293
+ }
2294
+
2295
+ @override
2296
+ void didChangeDependencies () {
2297
+ super .didChangeDependencies ();
2298
+ if (_animation == null || _previousTabController? .animation != _tabController.animation) {
2299
+ _setAnimation ();
2300
+ }
2301
+ if (_previousTabController != _tabController) {
2302
+ _previousTabController = _tabController;
2303
+ }
2304
+ }
2305
+
2306
+ void _setAnimation () {
2307
+ _animation? .dispose ();
2308
+ _animation = CurvedAnimation (
2309
+ parent: _tabController.animation! ,
2310
+ curve: Curves .fastOutSlowIn,
2311
+ );
2312
+ }
2313
+
2314
+ @override
2315
+ void dispose () {
2316
+ _animation? .dispose ();
2317
+ super .dispose ();
2318
+ }
2319
+
2259
2320
Widget _buildTabIndicator (
2260
2321
int tabIndex,
2261
2322
TabController tabController,
@@ -2290,44 +2351,27 @@ class TabPageSelector extends StatelessWidget {
2290
2351
return TabPageSelectorIndicator (
2291
2352
backgroundColor: background,
2292
2353
borderColor: selectedColorTween.end! ,
2293
- size: indicatorSize,
2294
- borderStyle: borderStyle ?? BorderStyle .solid,
2354
+ size: widget. indicatorSize,
2355
+ borderStyle: widget. borderStyle ?? BorderStyle .solid,
2295
2356
);
2296
2357
}
2297
2358
2298
2359
@override
2299
2360
Widget build (BuildContext context) {
2300
- final Color fixColor = color ?? Colors .transparent;
2301
- final Color fixSelectedColor = selectedColor ?? Theme .of (context).colorScheme.secondary;
2361
+ final Color fixColor = widget. color ?? Colors .transparent;
2362
+ final Color fixSelectedColor = widget. selectedColor ?? Theme .of (context).colorScheme.secondary;
2302
2363
final ColorTween selectedColorTween = ColorTween (begin: fixColor, end: fixSelectedColor);
2303
2364
final ColorTween previousColorTween = ColorTween (begin: fixSelectedColor, end: fixColor);
2304
- final TabController ? tabController = controller ?? DefaultTabController .maybeOf (context);
2305
2365
final MaterialLocalizations localizations = MaterialLocalizations .of (context);
2306
- assert (() {
2307
- if (tabController == null ) {
2308
- throw FlutterError (
2309
- 'No TabController for $runtimeType .\n '
2310
- 'When creating a $runtimeType , you must either provide an explicit TabController '
2311
- 'using the "controller" property, or you must ensure that there is a '
2312
- 'DefaultTabController above the $runtimeType .\n '
2313
- 'In this case, there was neither an explicit controller nor a default controller.' ,
2314
- );
2315
- }
2316
- return true ;
2317
- }());
2318
- final Animation <double > animation = CurvedAnimation (
2319
- parent: tabController! .animation! ,
2320
- curve: Curves .fastOutSlowIn,
2321
- );
2322
2366
return AnimatedBuilder (
2323
- animation: animation ,
2367
+ animation: _animation ! ,
2324
2368
builder: (BuildContext context, Widget ? child) {
2325
2369
return Semantics (
2326
- label: localizations.tabLabel (tabIndex: tabController .index + 1 , tabCount: tabController .length),
2370
+ label: localizations.tabLabel (tabIndex: _tabController .index + 1 , tabCount: _tabController .length),
2327
2371
child: Row (
2328
2372
mainAxisSize: MainAxisSize .min,
2329
- children: List <Widget >.generate (tabController .length, (int tabIndex) {
2330
- return _buildTabIndicator (tabIndex, tabController , selectedColorTween, previousColorTween);
2373
+ children: List <Widget >.generate (_tabController .length, (int tabIndex) {
2374
+ return _buildTabIndicator (tabIndex, _tabController , selectedColorTween, previousColorTween);
2331
2375
}).toList (),
2332
2376
),
2333
2377
);
0 commit comments