Commit 2116f00b authored by Adam Barth's avatar Adam Barth Committed by GitHub

Switch TabBar to sliver-based scrolling (#7964)

parent 1a066c84
...@@ -385,7 +385,7 @@ class TabBar extends StatefulWidget implements AppBarBottomWidget { ...@@ -385,7 +385,7 @@ class TabBar extends StatefulWidget implements AppBarBottomWidget {
} }
class _TabBarState extends State<TabBar> { class _TabBarState extends State<TabBar> {
final GlobalKey<ScrollableState> viewportKey = new GlobalKey<ScrollableState>(); final ScrollController _scrollController = new ScrollController();
TabController _controller; TabController _controller;
_ChangeAnimation _changeAnimation; _ChangeAnimation _changeAnimation;
...@@ -434,28 +434,25 @@ class _TabBarState extends State<TabBar> { ...@@ -434,28 +434,25 @@ class _TabBarState extends State<TabBar> {
// tabOffsets[tabOffsets.length] is the right edge of the last tab. // tabOffsets[tabOffsets.length] is the right edge of the last tab.
int get maxTabIndex => _indicatorPainter.tabOffsets.length - 2; int get maxTabIndex => _indicatorPainter.tabOffsets.length - 2;
double _tabCenteredScrollOffset(ScrollableState viewport, int tabIndex) { double _tabCenteredScrollOffset(int tabIndex) {
final List<double> tabOffsets = _indicatorPainter.tabOffsets; final List<double> tabOffsets = _indicatorPainter.tabOffsets;
assert(tabOffsets != null && tabIndex >= 0 && tabIndex <= maxTabIndex); assert(tabOffsets != null && tabIndex >= 0 && tabIndex <= maxTabIndex);
final ExtentScrollBehavior scrollBehavior = viewport.scrollBehavior; final ScrollPosition position = _scrollController.position;
final double viewportWidth = scrollBehavior.containerExtent;
final double tabCenter = (tabOffsets[tabIndex] + tabOffsets[tabIndex + 1]) / 2.0; final double tabCenter = (tabOffsets[tabIndex] + tabOffsets[tabIndex + 1]) / 2.0;
return (tabCenter - viewportWidth / 2.0) return (tabCenter - position.viewportDimension / 2.0)
.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset); .clamp(position.minScrollExtent, position.maxScrollExtent);
} }
void _scrollToCurrentIndex() { void _scrollToCurrentIndex() {
final ScrollableState viewport = viewportKey.currentState; final double offset = _tabCenteredScrollOffset(_currentIndex);
final double offset = _tabCenteredScrollOffset(viewport, _currentIndex); _scrollController.animateTo(offset, duration: kTabScrollDuration, curve: Curves.ease);
viewport.scrollTo(offset, duration: kTabScrollDuration);
} }
void _scrollToControllerValue() { void _scrollToControllerValue() {
final ScrollableState viewport = viewportKey.currentState; final double left = _currentIndex > 0 ? _tabCenteredScrollOffset(_currentIndex - 1) : null;
final double left = _currentIndex > 0 ? _tabCenteredScrollOffset(viewport, _currentIndex - 1) : null; final double middle = _tabCenteredScrollOffset(_currentIndex);
final double middle = _tabCenteredScrollOffset(viewport, _currentIndex); final double right = _currentIndex < maxTabIndex ? _tabCenteredScrollOffset(_currentIndex + 1) : null;
final double right = _currentIndex < maxTabIndex ? _tabCenteredScrollOffset(viewport, _currentIndex + 1) : null;
final double index = _controller.index.toDouble(); final double index = _controller.index.toDouble();
final double value = _controller.animation.value; final double value = _controller.animation.value;
...@@ -471,7 +468,7 @@ class _TabBarState extends State<TabBar> { ...@@ -471,7 +468,7 @@ class _TabBarState extends State<TabBar> {
else else
offset = right == null ? middle : lerpDouble(middle, right, value - index); offset = right == null ? middle : lerpDouble(middle, right, value - index);
viewport.scrollTo(offset); _scrollController.jumpTo(offset);
} }
void _handleTick() { void _handleTick() {
...@@ -582,10 +579,10 @@ class _TabBarState extends State<TabBar> { ...@@ -582,10 +579,10 @@ class _TabBarState extends State<TabBar> {
); );
if (config.isScrollable) { if (config.isScrollable) {
tabBar = new ScrollableViewport( tabBar = new SingleChildScrollView(
scrollableKey: viewportKey,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: tabBar controller: _scrollController,
child: tabBar,
); );
} }
......
...@@ -8,9 +8,10 @@ import 'package:flutter/rendering.dart'; ...@@ -8,9 +8,10 @@ import 'package:flutter/rendering.dart';
import 'basic.dart'; import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
import 'scroll_controller.dart';
import 'scroll_physics.dart';
import 'scrollable.dart'; import 'scrollable.dart';
/// A box in which a single widget can be scrolled. /// A box in which a single widget can be scrolled.
/// ///
/// This widget is useful when you have a single box that will normally be /// This widget is useful when you have a single box that will normally be
...@@ -41,6 +42,8 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -41,6 +42,8 @@ class SingleChildScrollView extends StatelessWidget {
this.scrollDirection: Axis.vertical, this.scrollDirection: Axis.vertical,
this.reverse: false, this.reverse: false,
this.padding, this.padding,
this.physics,
this.controller,
this.child, this.child,
}) : super(key: key) { }) : super(key: key) {
assert(scrollDirection != null); assert(scrollDirection != null);
...@@ -52,6 +55,10 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -52,6 +55,10 @@ class SingleChildScrollView extends StatelessWidget {
final EdgeInsets padding; final EdgeInsets padding;
final ScrollController controller;
final ScrollPhysics physics;
final Widget child; final Widget child;
AxisDirection _getDirection(BuildContext context) { AxisDirection _getDirection(BuildContext context) {
...@@ -73,6 +80,8 @@ class SingleChildScrollView extends StatelessWidget { ...@@ -73,6 +80,8 @@ class SingleChildScrollView extends StatelessWidget {
contents = new Padding(padding: padding, child: contents); contents = new Padding(padding: padding, child: contents);
return new Scrollable2( return new Scrollable2(
axisDirection: axisDirection, axisDirection: axisDirection,
controller: controller,
physics: physics,
viewportBuilder: (BuildContext context, ViewportOffset offset) { viewportBuilder: (BuildContext context, ViewportOffset offset) {
return new _SingleChildViewport( return new _SingleChildViewport(
key: key, key: key,
......
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