Commit 898c19d7 authored by najeira's avatar najeira Committed by Ian Hickson

add physics to TabBarView (#11150)

parent 744921fa
......@@ -795,6 +795,7 @@ class TabBarView extends StatefulWidget {
Key key,
@required this.children,
this.controller,
this.physics,
}) : assert(children != null), super(key: key);
/// This widget's selection and animation state.
......@@ -806,6 +807,17 @@ class TabBarView extends StatefulWidget {
/// One widget per tab.
final List<Widget> children;
/// How the page view should respond to user input.
///
/// For example, determines how the page view continues to animate after the
/// user stops dragging the page view.
///
/// The physics are modified to snap to page boundaries using
/// [PageScrollPhysics] prior to being used.
///
/// Defaults to matching platform conventions.
final ScrollPhysics physics;
@override
_TabBarViewState createState() => new _TabBarViewState();
}
......@@ -954,7 +966,7 @@ class _TabBarViewState extends State<TabBarView> {
onNotification: _handleScrollNotification,
child: new PageView(
controller: _pageController,
physics: _kTabBarViewPhysics,
physics: widget.physics == null ? _kTabBarViewPhysics : _kTabBarViewPhysics.applyTo(widget.physics),
children: _children,
),
);
......
......@@ -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/physics.dart';
import '../rendering/mock_canvas.dart';
import '../rendering/recording_canvas.dart';
......@@ -128,6 +129,24 @@ class TabIndicatorRecordingCanvas extends TestRecordingCanvas {
}
}
class TestScrollPhysics extends ScrollPhysics {
const TestScrollPhysics({ ScrollPhysics parent }) : super(parent: parent);
@override
TestScrollPhysics applyTo(ScrollPhysics ancestor) {
return new TestScrollPhysics(parent: buildParent(ancestor));
}
static final SpringDescription _kDefaultSpring = new SpringDescription.withDampingRatio(
mass: 0.5,
springConstant: 500.0,
ratio: 1.1,
);
@override
SpringDescription get spring => _kDefaultSpring;
}
void main() {
testWidgets('TabBar tap selects tab', (WidgetTester tester) async {
final List<String> tabs = <String>['A', 'B', 'C'];
......@@ -812,6 +831,53 @@ void main() {
expect(tabController.index, 2);
});
testWidgets('TabBarView scrolls end very close to a new page with custom physics', (WidgetTester tester) async {
final TabController tabController = new TabController(
vsync: const TestVSync(),
initialIndex: 1,
length: 3,
);
await tester.pumpWidget(
new SizedBox.expand(
child: new Center(
child: new SizedBox(
width: 400.0,
height: 400.0,
child: new TabBarView(
controller: tabController,
physics: const TestScrollPhysics(),
children: <Widget>[
const Center(child: const Text('0')),
const Center(child: const Text('1')),
const Center(child: const Text('2')),
],
),
),
),
),
);
expect(tabController.index, 1);
final PageView pageView = tester.widget(find.byType(PageView));
final PageController pageController = pageView.controller;
final ScrollPosition position = pageController.position;
// The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
// page 1 is at 400.0, page 2 is at 800.0.
expect(position.pixels, 400.0);
// Not close enough to switch to page 2
pageController.jumpTo(800.0 - 1.25 * position.physics.tolerance.distance);
expect(tabController.index, 1);
// Close enough to switch to page 2
pageController.jumpTo(800.0 - 0.75 * position.physics.tolerance.distance);
expect(tabController.index, 2);
});
testWidgets('Scrollable TabBar with a non-zero TabController initialIndex', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/9374
......
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