
Set the scrollOffset of a widget's Scrollable ancestor so that the widget is centered within the scrollable. A future CL will add support for specifying exactly where the widget appears. The scroll can be animated by specifying the animation: parameter. Changed the duration Scrollable.scrollTo() parameter from a Duration to an AnimationPerformance so that one can configure all aspects of the animation. The caller may also listen to the animation to schedule other work while it updates or when its status changes. complete
119 lines
3.7 KiB
Dart
119 lines
3.7 KiB
Dart
// 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 'package:sky/animation/animated_value.dart';
|
|
import 'package:sky/animation/animation_performance.dart';
|
|
import 'package:sky/animation/curves.dart';
|
|
import 'package:sky/base/lerp.dart';
|
|
import 'package:sky/painting/box_painter.dart';
|
|
import 'package:sky/painting/text_style.dart';
|
|
import 'package:sky/rendering/box.dart';
|
|
import 'package:sky/theme/colors.dart';
|
|
import 'package:sky/widgets/basic.dart';
|
|
import 'package:sky/widgets/block_viewport.dart';
|
|
import 'package:sky/widgets/card.dart';
|
|
import 'package:sky/widgets/icon.dart';
|
|
import 'package:sky/widgets/scrollable.dart';
|
|
import 'package:sky/widgets/scaffold.dart';
|
|
import 'package:sky/widgets/theme.dart';
|
|
import 'package:sky/widgets/tool_bar.dart';
|
|
import 'package:sky/widgets/framework.dart';
|
|
import 'package:sky/widgets/task_description.dart';
|
|
|
|
class CardModel {
|
|
CardModel(this.value, this.height, this.color);
|
|
int value;
|
|
double height;
|
|
Color color;
|
|
String get label => "Card $value";
|
|
Key get key => new Key.fromObjectIdentity(this);
|
|
}
|
|
|
|
class EnsureVisibleApp extends App {
|
|
|
|
static const TextStyle cardLabelStyle =
|
|
const TextStyle(color: white, fontSize: 18.0, fontWeight: bold);
|
|
|
|
List<CardModel> cardModels;
|
|
BlockViewportLayoutState layoutState = new BlockViewportLayoutState();
|
|
ScrollListener scrollListener;
|
|
AnimationPerformance scrollAnimation;
|
|
|
|
void initState() {
|
|
List<double> cardHeights = <double>[
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
|
|
];
|
|
cardModels = new List.generate(cardHeights.length, (i) {
|
|
Color color = lerpColor(Red[300], Blue[900], i / cardHeights.length);
|
|
return new CardModel(i, cardHeights[i], color);
|
|
});
|
|
|
|
scrollAnimation = new AnimationPerformance()
|
|
..duration = const Duration(milliseconds: 200)
|
|
..variable = new AnimatedValue<double>(0.0, curve: ease);
|
|
|
|
super.initState();
|
|
}
|
|
|
|
EventDisposition handleTap(Widget target) {
|
|
ensureWidgetIsVisible(target, animation: scrollAnimation);
|
|
return EventDisposition.processed;
|
|
}
|
|
|
|
Widget builder(int index) {
|
|
if (index >= cardModels.length)
|
|
return null;
|
|
CardModel cardModel = cardModels[index];
|
|
Widget card = new Card(
|
|
color: cardModel.color,
|
|
child: new Container(
|
|
height: cardModel.height,
|
|
padding: const EdgeDims.all(8.0),
|
|
child: new Center(child: new Text(cardModel.label, style: cardLabelStyle))
|
|
)
|
|
);
|
|
return new Listener(
|
|
key: cardModel.key,
|
|
onGestureTap: (_) { return handleTap(card); },
|
|
child: card
|
|
);
|
|
}
|
|
|
|
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]),
|
|
child: new VariableHeightScrollable(
|
|
builder: builder,
|
|
token: cardModels.length,
|
|
layoutState: layoutState
|
|
)
|
|
);
|
|
|
|
return new IconTheme(
|
|
data: const IconThemeData(color: IconThemeColor.white),
|
|
child: new Theme(
|
|
data: new ThemeData(
|
|
brightness: ThemeBrightness.light,
|
|
primarySwatch: Blue,
|
|
accentColor: RedAccent[200]
|
|
),
|
|
child: new TaskDescription(
|
|
label: 'Cards',
|
|
child: new Scaffold(
|
|
toolbar: new ToolBar(center: new Text('Tap a Card')),
|
|
body: cardCollection
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
runApp(new EnsureVisibleApp());
|
|
}
|