From 7edec88632d24a1043fdc7e92470611356ff7aef Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Tue, 8 Aug 2017 10:14:35 -0700 Subject: [PATCH] Allow tapping on TabBar indicator to switch tabs (#11525) * Allow tapping on TabBar indicator to switch tabs * fix semantics * review comments --- packages/flutter/lib/src/material/tabs.dart | 10 ++--- packages/flutter/test/material/tabs_test.dart | 41 ++++++++++++++++++- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index c82f439d8a..9f846a2595 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -737,7 +737,10 @@ class _TabBarState extends State { children: [ new InkWell( onTap: () { _handleTap(index); }, - child: wrappedTabs[index], + child: new Padding( + padding: new EdgeInsets.only(bottom: widget.indicatorWeight), + child: wrappedTabs[index], + ), ), new Semantics( selected: index == _currentIndex, @@ -753,9 +756,7 @@ class _TabBarState extends State { Widget tabBar = new CustomPaint( painter: _indicatorPainter, - child: new Padding( - padding: new EdgeInsets.only(bottom: widget.indicatorWeight), - child: new _TabStyle( + child: new _TabStyle( animation: kAlwaysDismissedAnimation, selected: false, labelColor: widget.labelColor, @@ -767,7 +768,6 @@ class _TabBarState extends State { children: wrappedTabs, ), ), - ), ); if (widget.isScrollable) { diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index 8812b9c5a8..e46caf16e5 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -7,6 +7,7 @@ import 'dart:ui' show SemanticsFlags, SemanticsAction; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter/physics.dart'; import '../rendering/mock_canvas.dart'; @@ -1007,14 +1008,14 @@ void main() { actions: SemanticsAction.tap.index, flags: SemanticsFlags.isSelected.index, label: 'TAB #0\nTab 1 of 2', - rect: new Rect.fromLTRB(0.0, 0.0, 108.0, 46.0), + rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight), transform: new Matrix4.translationValues(0.0, 276.0, 0.0), ), new TestSemantics( id: 5, actions: SemanticsAction.tap.index, label: 'TAB #1\nTab 2 of 2', - rect: new Rect.fromLTRB(0.0, 0.0, 108.0, 46.0), + rect: new Rect.fromLTRB(0.0, 0.0, 108.0, kTextTabBarHeight), transform: new Matrix4.translationValues(108.0, 276.0, 0.0), ), ]), @@ -1120,4 +1121,40 @@ void main() { expect(find.text('PAGE'), findsOneWidget); }); + testWidgets('can tap on indicator at very bottom of TabBar to switch tabs', (WidgetTester tester) async { + final TabController controller = new TabController( + vsync: const TestVSync(), + length: 2, + initialIndex: 0, + ); + + await tester.pumpWidget( + new Material( + child: new Column( + children: [ + new TabBar( + controller: controller, + indicatorWeight: 30.0, + tabs: const [const Tab(text: 'TAB1'), const Tab(text: 'TAB2')], + ), + new Flexible( + child: new TabBarView( + controller: controller, + children: const [const Text('PAGE1'), const Text('PAGE2')], + ), + ), + ], + ), + ), + ); + + expect(controller.index, 0); + + final Offset bottomRight = tester.getBottomRight(find.byType(TabBar)) - const Offset(1.0, 1.0); + final TestGesture gesture = await tester.startGesture(bottomRight); + await gesture.up(); + await tester.pumpAndSettle(); + + expect(controller.index, 1); + }); }