Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: sky/sdk/example/widgets/card_collection.dart

Issue 1227963003: Card "swipe-away" dismiss version 3: Uses BlockViewport (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Updates per review feedback Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sky/sdk/lib/widgets/block_viewport.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/example/widgets/card_collection.dart
diff --git a/sky/sdk/example/widgets/card_collection.dart b/sky/sdk/example/widgets/card_collection.dart
index eb4f16797ea1ae19e6ce9735d5cf1de81e5c6911..170e5c3057b7aa8eba1c5c91216709d307c096c9 100644
--- a/sky/sdk/example/widgets/card_collection.dart
+++ b/sky/sdk/example/widgets/card_collection.dart
@@ -6,35 +6,86 @@ import 'dart:sky' as sky;
import 'package:vector_math/vector_math.dart';
import 'package:sky/animation/animation_performance.dart';
+import 'package:sky/animation/scroll_behavior.dart';
import 'package:sky/base/lerp.dart';
import 'package:sky/painting/text_style.dart';
import 'package:sky/theme/colors.dart';
import 'package:sky/widgets/animated_container.dart';
import 'package:sky/widgets/basic.dart';
+import 'package:sky/widgets/block_viewport.dart';
import 'package:sky/widgets/card.dart';
import 'package:sky/widgets/scaffold.dart';
+import 'package:sky/widgets/scrollable.dart';
import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/tool_bar.dart';
import 'package:sky/widgets/widget.dart';
const int _kCardDismissFadeoutMS = 300;
-const double _kMinCardFlingVelocity = 0.4;
-const double _kDismissCardThreshold = 0.70;
+const double _kMinFlingVelocity = 700.0;
+const double _kMinFlingVelocityDelta = 400.0;
+const double _kDismissCardThreshold = 0.6;
+
+class VariableHeightScrollable extends Scrollable {
abarth-chromium 2015/07/10 02:37:27 This class came out great. Nice and clean.
+ VariableHeightScrollable({
+ String key,
+ this.builder,
+ this.token
+ }) : super(key: key);
+
+ IndexedBuilder builder;
+ Object token;
+
+ void syncFields(VariableHeightScrollable source) {
+ builder = source.builder;
+ token = source.token;
+ super.syncFields(source);
+ }
+
+ ScrollBehavior createScrollBehavior() => new OverscrollBehavior();
+ OverscrollBehavior get scrollBehavior => super.scrollBehavior;
+
+ void _handleSizeChanged(Size newSize) {
+ setState(() {
+ scrollBehavior.containerHeight = newSize.height;
+ scrollBehavior.contentsHeight = 5000.0;
abarth-chromium 2015/07/10 02:37:27 Where does this number come from? Maybe BlockView
hansmuller 2015/07/10 15:45:58 Yes. For this case maybe BlockViewport just needs
+ });
+ }
+
+ Widget buildContent() {
+ Widget viewport = new BlockViewport(
+ builder: builder,
+ startOffset: scrollOffset,
+ token: token
+ );
+ return new SizeObserver(child: viewport, callback: _handleSizeChanged);
abarth-chromium 2015/07/10 02:37:27 The style we've used in other framework widgets is
hansmuller 2015/07/10 15:45:58 Sure, I'll conform. I've tried to limit the depth
+ }
+}
class CardCollectionApp extends App {
final TextStyle cardLabelStyle =
new TextStyle(color: White, fontSize: 18.0, fontWeight: bold);
+ final List<double> cardHeights = [
+ 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0,
+ 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0,
+ 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0
+ ];
+
+ List<int> visibleCardIndices;
+
CardCollectionApp() {
_activeCardTransform = new AnimatedContainer()
..position = new AnimatedType<Point>(Point.origin)
..opacity = new AnimatedType<double>(1.0, end: 0.0);
+
_activeCardAnimation = _activeCardTransform.createPerformance(
[_activeCardTransform.position, _activeCardTransform.opacity],
duration: new Duration(milliseconds: _kCardDismissFadeoutMS));
_activeCardAnimation.addListener(_handleAnimationProgressChanged);
+
+ visibleCardIndices = new List.generate(cardHeights.length, (i) => i);
}
int _activeCardIndex = -1;
@@ -43,7 +94,6 @@ class CardCollectionApp extends App {
double _activeCardWidth;
double _activeCardDragX = 0.0;
bool _activeCardDragUnderway = false;
- Set<int> _dismissedCardIndices = new Set<int>();
Point get _activeCardDragEndPoint {
return new Point(_activeCardDragX.sign * _activeCardWidth * _kDismissCardThreshold, 0.0);
@@ -52,7 +102,7 @@ class CardCollectionApp extends App {
void _handleAnimationProgressChanged() {
setState(() {
if (_activeCardAnimation.isCompleted && !_activeCardDragUnderway)
- _dismissedCardIndices.add(_activeCardIndex);
+ visibleCardIndices.remove(_activeCardIndex);
});
}
@@ -92,30 +142,37 @@ class CardCollectionApp extends App {
setState(() {
_activeCardDragUnderway = false;
if (_activeCardAnimation.isCompleted)
- _dismissedCardIndices.add(_activeCardIndex);
+ visibleCardIndices.remove(_activeCardIndex);
else if (!_activeCardAnimation.isAnimating)
_activeCardAnimation.progress = 0.0;
});
}
+ bool _isHorizontalFlingGesture(sky.GestureEvent event) {
+ double vx = event.velocityX.abs();
+ double vy = event.velocityY.abs();
+ return vx - vy > _kMinFlingVelocityDelta && vx > _kMinFlingVelocity;
+ }
+
void _handleFlingStart(sky.GestureEvent event) {
if (_activeCardWidth == null || _activeCardIndex < 0)
return;
_activeCardDragUnderway = false;
- double velocityX = event.velocityX / 1000;
- if (velocityX.abs() >= _kMinCardFlingVelocity) {
+
+ if (_isHorizontalFlingGesture(event)) {
double distance = 1.0 - _activeCardAnimation.progress;
if (distance > 0.0) {
- double duration = 150.0 * distance / velocityX.abs();
- _activeCardDragX = velocityX.sign;
+ double duration = 250.0 * 1000.0 * distance / event.velocityX.abs();
+ _activeCardDragX = event.velocityX.sign;
_activeCardAnimation.timeline.animateTo(1.0, duration: duration);
}
}
}
- Widget _buildCard(int index, Color color) {
- Widget label = new Center(child: new Text("Item ${index}", style: cardLabelStyle));
+ Widget _buildCard(int cardIndex) {
+ Widget label = new Center(child: new Text("Item ${cardIndex}", style: cardLabelStyle));
+ Color color = lerpColor(Red[500], Blue[500], cardIndex / cardHeights.length);
Widget card = new Card(
child: new Padding(child: label, padding: const EdgeDims.all(8.0)),
color: color
@@ -125,7 +182,7 @@ class CardCollectionApp extends App {
// the user starts dragging it. Currently this causes Sky to drop the
// rest of the pointer gesture, see https://github.com/domokit/mojo/issues/312.
// As a workaround, always create the Transform and Opacity nodes.
- if (index == _activeCardIndex) {
+ if (cardIndex == _activeCardIndex) {
card = _activeCardTransform.build(card);
} else {
card = new Transform(child: card, transform: new Matrix4.identity());
@@ -133,8 +190,9 @@ class CardCollectionApp extends App {
}
return new Listener(
- child: card,
- onPointerDown: (event) { _handlePointerDown(event, index); },
+ key: "$cardIndex",
+ child: new Container(child: card, height: cardHeights[cardIndex]),
+ onPointerDown: (event) { _handlePointerDown(event, cardIndex); },
onPointerMove: _handlePointerMove,
onPointerUp: _handlePointerUpOrCancel,
onPointerCancel: _handlePointerUpOrCancel,
@@ -142,31 +200,25 @@ class CardCollectionApp extends App {
);
}
- Widget _buildCardCollection(List<double> heights) {
- List<Widget> items = <Widget>[];
- for(int index = 0; index < heights.length; index++) {
- if (_dismissedCardIndices.contains(index))
- continue;
- Color color = lerpColor(Red[500], Blue[500], index / heights.length);
- items.add(new Container(
- child: _buildCard(index, color),
- height: heights[index]
- ));
- }
+ Widget _builder(int index) {
+ if (index >= visibleCardIndices.length)
+ return null;
+ return _buildCard(visibleCardIndices[index]);
+ }
- return new Container(
- child: new SizeObserver(child: new Block(items), callback: _handleSizeChanged),
+ Widget build() {
+ Widget cardCollection = new Container(
padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
- decoration: new BoxDecoration(backgroundColor: Theme.of(this).primarySwatch[50])
+ decoration: new BoxDecoration(backgroundColor: Theme.of(this).primarySwatch[50]),
+ child: new VariableHeightScrollable(
+ builder: _builder,
+ token: visibleCardIndices.length
+ )
);
- }
- Widget build() {
return new Scaffold(
toolbar: new ToolBar(center: new Text('Swipe Away')),
- body: _buildCardCollection(
- [48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0,
- 48.0, 64.0, 82.0, 46.0, 60.0, 55.0, 84.0, 96.0, 50.0])
+ body: new SizeObserver(child: cardCollection, callback: _handleSizeChanged)
);
}
}
« no previous file with comments | « no previous file | sky/sdk/lib/widgets/block_viewport.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698