From 707d8606c84b88fb3bb6730ee718455f5a2c534d Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 10 Sep 2015 12:03:35 -0700 Subject: [PATCH] Don't register gesture detectors when Scrollable can't scroll Previously, if you used a number of nested Blocks, they'd each try to register drag gesture detectors even though they can't actually scroll. This CL teaches Scrollable to watch for drag gestures only when it can actually scroll. --- .../lib/src/animation/scroll_behavior.dart | 3 +++ .../flutter/lib/src/widgets/scrollable.dart | 23 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/flutter/lib/src/animation/scroll_behavior.dart b/packages/flutter/lib/src/animation/scroll_behavior.dart index cd209761f4d..14d47b0450f 100644 --- a/packages/flutter/lib/src/animation/scroll_behavior.dart +++ b/packages/flutter/lib/src/animation/scroll_behavior.dart @@ -19,6 +19,9 @@ abstract class ScrollBehavior { /// The new scroll offset to use when the user attempts to scroll from the given offset by the given delta double applyCurve(double scrollOffset, double scrollDelta); + + /// Whether this scroll behavior currently permits scrolling + bool get isScrollable => true; } /// A scroll behavior for a scrollable widget with linear extent diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 2fb8efaa99e..2617f3505bf 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -9,6 +9,7 @@ import 'dart:sky' as sky; import 'package:newton/newton.dart'; import 'package:sky/animation.dart'; import 'package:sky/gestures/constants.dart'; +import 'package:sky/gestures/scroll.dart'; import 'package:sky/src/rendering/box.dart'; import 'package:sky/src/rendering/viewport.dart'; import 'package:sky/src/widgets/basic.dart'; @@ -79,13 +80,25 @@ abstract class Scrollable extends StatefulComponent { Widget buildContent(); + GestureDragUpdateCallback _getDragUpdateHandler(ScrollDirection direction) { + if (scrollDirection != direction || !scrollBehavior.isScrollable) + return null; + return scrollBy; + } + + GestureDragEndCallback _getDragEndHandler(ScrollDirection direction) { + if (scrollDirection != direction || !scrollBehavior.isScrollable) + return null; + return _maybeSettleScrollOffset; + } + Widget build() { return new GestureDetector( - onVerticalDragUpdate: scrollDirection == ScrollDirection.vertical ? scrollBy : null, - onVerticalDragEnd: scrollDirection == ScrollDirection.vertical ? _maybeSettleScrollOffset : null, - onHorizontalDragUpdate: scrollDirection == ScrollDirection.horizontal ? scrollBy : null, - onHorizontalDragEnd: scrollDirection == ScrollDirection.horizontal ? _maybeSettleScrollOffset : null, - onFling: _handleFling, + onVerticalDragUpdate: _getDragUpdateHandler(ScrollDirection.vertical), + onVerticalDragEnd: _getDragEndHandler(ScrollDirection.vertical), + onHorizontalDragUpdate: _getDragUpdateHandler(ScrollDirection.horizontal), + onHorizontalDragEnd: _getDragEndHandler(ScrollDirection.horizontal), + onFling: scrollBehavior.isScrollable ? _handleFling : null, child: new Listener( child: buildContent(), onPointerDown: _handlePointerDown,