diff --git a/examples/stocks-fn/stocklist.dart b/examples/stocks-fn/stocklist.dart index 50c64f36001..d904ef1c2a8 100644 --- a/examples/stocks-fn/stocklist.dart +++ b/examples/stocks-fn/stocklist.dart @@ -8,7 +8,7 @@ class Stocklist extends FixedHeightScrollable { Object key, this.stocks, this.query - }) : super(key: key, minOffset: 0.0); + }) : super(key: key, scrollCurve: new BoundedScrollCurve(minOffset: 0.0)); List buildItems(int start, int count) { return stocks diff --git a/examples/stocks-fn/stocksapp.dart b/examples/stocks-fn/stocksapp.dart index d392d659c73..7923c7197b4 100644 --- a/examples/stocks-fn/stocksapp.dart +++ b/examples/stocks-fn/stocksapp.dart @@ -1,6 +1,7 @@ library stocksapp; import '../../framework/fn.dart'; +import '../../framework/animation/scroll_curve.dart'; import '../../framework/components/drawer.dart'; import '../../framework/components/drawer_header.dart'; import '../../framework/components/fixed_height_scrollable.dart'; diff --git a/framework/animation/scroll_curve.dart b/framework/animation/scroll_curve.dart new file mode 100644 index 00000000000..07940aee133 --- /dev/null +++ b/framework/animation/scroll_curve.dart @@ -0,0 +1,26 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:math' as math; + +abstract class ScrollCurve { + // Returns the new scroll offset. + double apply(double scrollOffset, double scrollDelta); +} + +class BoundedScrollCurve extends ScrollCurve { + double minOffset; + double maxOffset; + + BoundedScrollCurve({this.minOffset: 0.0, this.maxOffset}); + + double apply(double scrollOffset, double scrollDelta) { + double newScrollOffset = scrollOffset + scrollDelta; + if (minOffset != null) + newScrollOffset = math.max(minOffset, newScrollOffset); + if (maxOffset != null) + newScrollOffset = math.min(maxOffset, newScrollOffset); + return newScrollOffset; + } +} diff --git a/framework/components/fixed_height_scrollable.dart b/framework/components/fixed_height_scrollable.dart index fcb36da06c1..4f3a9d9116c 100644 --- a/framework/components/fixed_height_scrollable.dart +++ b/framework/components/fixed_height_scrollable.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '../animation/scroll_curve.dart'; import '../fn.dart'; import 'dart:sky' as sky; import 'scrollable.dart'; @@ -27,10 +28,8 @@ abstract class FixedHeightScrollable extends Scrollable { FixedHeightScrollable({ Object key, - double minOffset, - double maxOffset - }) : super(key: key, minOffset: minOffset, maxOffset: maxOffset) { - } + ScrollCurve scrollCurve + }) : super(key: key, scrollCurve: scrollCurve); void didMount() { super.didMount(); diff --git a/framework/components/scrollable.dart b/framework/components/scrollable.dart index 9a62a067dd1..20f285866ef 100644 --- a/framework/components/scrollable.dart +++ b/framework/components/scrollable.dart @@ -3,24 +3,19 @@ // found in the LICENSE file. import '../animation/fling_curve.dart'; +import '../animation/scroll_curve.dart'; import '../fn.dart'; import 'dart:sky' as sky; abstract class Scrollable extends Component { - double minOffset; - double maxOffset; - + ScrollCurve scrollCurve; double get scrollOffset => _scrollOffset; double _scrollOffset = 0.0; FlingCurve _flingCurve; int _flingAnimationId; - Scrollable({ - Object key, - this.minOffset, - this.maxOffset - }) : super(key: key) { + Scrollable({Object key, this.scrollCurve}) : super(key: key) { events.listen('gestureflingstart', _handleFlingStart); events.listen('gestureflingcancel', _handleFlingCancel); events.listen('gesturescrollupdate', _handleScrollUpdate); @@ -33,15 +28,9 @@ abstract class Scrollable extends Component { } bool scrollBy(double scrollDelta) { - var newScrollOffset = _scrollOffset + scrollDelta; - if (minOffset != null && newScrollOffset < minOffset) - newScrollOffset = minOffset; - else if (maxOffset != null && newScrollOffset > maxOffset) - newScrollOffset = maxOffset; - + var newScrollOffset = scrollCurve.apply(_scrollOffset, scrollDelta); if (newScrollOffset == _scrollOffset) return false; - setState(() { _scrollOffset = newScrollOffset; });