Update TabBar indicator painter when tab controller changes (#14825)
diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart
index 106ac2d..03a0a04 100644
--- a/packages/flutter/lib/src/material/tabs.dart
+++ b/packages/flutter/lib/src/material/tabs.dart
@@ -752,14 +752,15 @@
@override
void didUpdateWidget(TabBar oldWidget) {
super.didUpdateWidget(oldWidget);
- if (widget.controller != oldWidget.controller)
+ if (widget.controller != oldWidget.controller) {
_updateTabController();
-
- if (widget.indicatorColor != oldWidget.indicatorColor ||
+ _initIndicatorPainter();
+ } else if (widget.indicatorColor != oldWidget.indicatorColor ||
widget.indicatorWeight != oldWidget.indicatorWeight ||
widget.indicatorSize != oldWidget.indicatorSize ||
- widget.indicator != oldWidget.indicator)
+ widget.indicator != oldWidget.indicator) {
_initIndicatorPainter();
+ }
if (widget.tabs.length > oldWidget.tabs.length) {
final int delta = widget.tabs.length - oldWidget.tabs.length;
diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart
index a71c460..89de8f2 100644
--- a/packages/flutter/test/material/tabs_test.dart
+++ b/packages/flutter/test/material/tabs_test.dart
@@ -1650,4 +1650,71 @@
expect(() => new Tab(icon: new Container(), text: 'foo', child: new Container()), throwsAssertionError);
expect(() => new Tab(text: 'foo', child: new Container()), throwsAssertionError);
});
+
+
+ testWidgets('TabController changes', (WidgetTester tester) async {
+ // This is a regression test for https://github.com/flutter/flutter/issues/14812
+
+ Widget buildFrame(TabController controller) {
+ return boilerplate(
+ child: new Container(
+ alignment: Alignment.topLeft,
+ child: new TabBar(
+ controller: controller,
+ tabs: <Tab>[
+ const Tab(text: 'LEFT'),
+ const Tab(text: 'RIGHT'),
+ ],
+ ),
+ ),
+ );
+ }
+
+ final TabController controller1 = new TabController(
+ vsync: const TestVSync(),
+ length: 2,
+ initialIndex: 0,
+ );
+
+ final TabController controller2 = new TabController(
+ vsync: const TestVSync(),
+ length: 2,
+ initialIndex: 0,
+ );
+
+ await tester.pumpWidget(buildFrame(controller1));
+ await tester.pumpWidget(buildFrame(controller2));
+ expect(controller1.index, 0);
+ expect(controller2.index, 0);
+
+ const double indicatorWeight = 2.0;
+ final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
+ expect(tabBarBox.size.height, 48.0); // 48 = _kTabHeight(46) + indicatorWeight(2.0)
+
+ final double indicatorY = 48.0 - indicatorWeight / 2.0;
+ double indicatorLeft = indicatorWeight / 2.0;
+ double indicatorRight = 400.0 - indicatorWeight / 2.0; // 400 = screen_width / 2
+ expect(tabBarBox, paints..line(
+ strokeWidth: indicatorWeight,
+ p1: new Offset(indicatorLeft, indicatorY),
+ p2: new Offset(indicatorRight, indicatorY),
+ ));
+
+ await tester.tap(find.text('RIGHT'));
+ await tester.pumpAndSettle();
+ expect(controller1.index, 0);
+ expect(controller2.index, 1);
+
+ // Verify that the TabBar's _IndicatorPainter is now listening to
+ // tabController2.
+
+ indicatorLeft = 400.0 + indicatorWeight / 2.0;
+ indicatorRight = 800.0 - indicatorWeight / 2.0;
+ expect(tabBarBox, paints..line(
+ strokeWidth: indicatorWeight,
+ p1: new Offset(indicatorLeft, indicatorY),
+ p2: new Offset(indicatorRight, indicatorY),
+ ));
+ });
+
}