Commit dc4fe525 authored by Hans Muller's avatar Hans Muller

Merge pull request #2350 from HansMuller/tab_scroll

Restore scrolled tabs support 
parents 74ffda0f 4eae547c
......@@ -704,7 +704,8 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
void _updateScrollBehavior() {
scrollTo(scrollBehavior.updateExtents(
containerExtent: config.scrollDirection == Axis.vertical ? _viewportSize.height : _viewportSize.width,
contentExtent: _tabWidths.reduce((double sum, double width) => sum + width)
contentExtent: _tabWidths.reduce((double sum, double width) => sum + width),
scrollOffset: scrollOffset
));
}
......@@ -780,7 +781,7 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
);
if (config.isScrollable) {
child: new Viewport(
return new Viewport(
scrollDirection: Axis.horizontal,
paintOffset: scrollOffsetToPixelDelta(scrollOffset),
onPaintOffsetUpdateNeeded: _handlePaintOffsetUpdateNeeded,
......
......@@ -7,12 +7,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
Widget buildFrame({ List<String> tabs, String value, bool isScrollable: false }) {
Widget buildFrame({ List<String> tabs, String value, bool isScrollable: false, Key tabBarKey }) {
return new Material(
child: new TabBarSelection<String>(
value: value,
values: tabs,
child: new TabBar<String>(
key: tabBarKey,
labels: new Map<String, TabLabel>.fromIterable(tabs, value: (String tab) => new TabLabel(text: tab)),
isScrollable: isScrollable
)
......@@ -98,4 +99,48 @@ void main() {
expect(selection.value, equals('A'));
});
});
test('Scrollable TabBar tap centers selected tab', () {
testWidgets((WidgetTester tester) {
List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
Key tabBarKey = new Key('TabBar');
tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey));
TabBarSelectionState<String> selection = TabBarSelection.of(tester.findText('AAAAAA'));
expect(selection, isNotNull);
expect(selection.value, equals('AAAAAA'));
expect(tester.getSize(tester.findElementByKey(tabBarKey)).width, equals(800.0));
// The center of the FFFFFF item is to the right of the TabBar's center
expect(tester.getCenter(tester.findText('FFFFFF')).x, greaterThan(401.0));
tester.tap(tester.findText('FFFFFF'));
tester.pump();
tester.pump(const Duration(seconds: 1)); // finish the scroll animation
expect(selection.value, equals('FFFFFF'));
// The center of the FFFFFF item is now at the TabBar's center
expect(tester.getCenter(tester.findText('FFFFFF')).x, closeTo(400.0, 1.0));
});
});
test('TabBar can be scrolled independent of the selection', () {
testWidgets((WidgetTester tester) {
List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
Key tabBarKey = new Key('TabBar');
tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey));
TabBarSelectionState<String> selection = TabBarSelection.of(tester.findText('AAAAAA'));
expect(selection, isNotNull);
expect(selection.value, equals('AAAAAA'));
// Fling-scroll the TabBar to the left
expect(tester.getCenter(tester.findText('HHHHHH')).x, lessThan(700.0));
tester.fling(tester.findElementByKey(tabBarKey), const Offset(-20.0, 0.0), 1000.0);
tester.pump();
tester.pump(const Duration(seconds: 1)); // finish the scroll animation
expect(tester.getCenter(tester.findText('HHHHHH')).x, lessThan(500.0));
// Scrolling the TabBar doesn't change the selection
expect(selection.value, equals('AAAAAA'));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment