mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

This patch converts drawer to using the "openDialog" pattern for managing its state. Currently, the drawer entrance and exit animation aren't integrated with the navigator's animation system because the drawer's animations can be stopped and reversed, which the navigator can't yet understand. That means dismissing the drawer via the system back button causes the drawer to be removed instanteously. Fixes #715 Fixes #1187
172 lines
4.7 KiB
Dart
172 lines
4.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/material.dart';
|
|
import 'package:sky/painting.dart';
|
|
import 'package:sky/widgets.dart';
|
|
|
|
class CardModel {
|
|
CardModel(this.value, this.size, this.color);
|
|
int value;
|
|
Size size;
|
|
Color color;
|
|
String get label => "Card $value";
|
|
Key get key => new ObjectKey(this);
|
|
}
|
|
|
|
class PageableListApp extends StatefulComponent {
|
|
PageableListApp({ this.navigator });
|
|
|
|
final NavigatorState navigator;
|
|
|
|
PageableListAppState createState() => new PageableListAppState();
|
|
}
|
|
|
|
class PageableListAppState extends State<PageableListApp> {
|
|
void initState() {
|
|
super.initState();
|
|
List<Size> cardSizes = [
|
|
[100.0, 300.0], [300.0, 100.0], [200.0, 400.0], [400.0, 400.0], [300.0, 400.0]
|
|
]
|
|
.map((args) => new Size(args[0], args[1]))
|
|
.toList();
|
|
|
|
cardModels = new List.generate(cardSizes.length, (i) {
|
|
Color color = Color.lerp(Colors.red[300], Colors.blue[900], i / cardSizes.length);
|
|
return new CardModel(i, cardSizes[i], color);
|
|
});
|
|
}
|
|
|
|
static const TextStyle cardLabelStyle =
|
|
const TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: bold);
|
|
|
|
List<CardModel> cardModels;
|
|
Size pageSize = new Size(200.0, 200.0);
|
|
ScrollDirection scrollDirection = ScrollDirection.horizontal;
|
|
bool itemsWrap = false;
|
|
|
|
void updatePageSize(Size newSize) {
|
|
setState(() {
|
|
pageSize = newSize;
|
|
});
|
|
}
|
|
|
|
Widget buildCard(BuildContext context, CardModel cardModel) {
|
|
Widget card = new Card(
|
|
color: cardModel.color,
|
|
child: new Container(
|
|
width: cardModel.size.width,
|
|
height: cardModel.size.height,
|
|
padding: const EdgeDims.all(8.0),
|
|
child: new Center(child: new Text(cardModel.label, style: cardLabelStyle))
|
|
)
|
|
);
|
|
|
|
BoxConstraints constraints = (scrollDirection == ScrollDirection.vertical)
|
|
? new BoxConstraints.tightFor(height: pageSize.height)
|
|
: new BoxConstraints.tightFor(width: pageSize.width);
|
|
|
|
return new Container(
|
|
key: cardModel.key,
|
|
constraints: constraints,
|
|
child: new Center(child: card)
|
|
);
|
|
}
|
|
|
|
void switchScrollDirection() {
|
|
setState(() {
|
|
scrollDirection = (scrollDirection == ScrollDirection.vertical)
|
|
? ScrollDirection.horizontal
|
|
: ScrollDirection.vertical;
|
|
});
|
|
}
|
|
|
|
void toggleItemsWrap() {
|
|
setState(() {
|
|
itemsWrap = !itemsWrap;
|
|
});
|
|
}
|
|
|
|
void _showDrawer() {
|
|
showDrawer(
|
|
navigator: config.navigator,
|
|
child: new Block([
|
|
new DrawerHeader(child: new Text('Options')),
|
|
new DrawerItem(
|
|
icon: 'navigation/more_horiz',
|
|
selected: scrollDirection == ScrollDirection.horizontal,
|
|
child: new Text('Horizontal Layout'),
|
|
onPressed: switchScrollDirection
|
|
),
|
|
new DrawerItem(
|
|
icon: 'navigation/more_vert',
|
|
selected: scrollDirection == ScrollDirection.vertical,
|
|
child: new Text('Vertical Layout'),
|
|
onPressed: switchScrollDirection
|
|
),
|
|
new DrawerItem(
|
|
onPressed: toggleItemsWrap,
|
|
child: new Row([
|
|
new Flexible(child: new Text('Scrolling wraps around')),
|
|
new Checkbox(value: itemsWrap)
|
|
])
|
|
)
|
|
])
|
|
);
|
|
}
|
|
|
|
Widget buildToolBar() {
|
|
return new ToolBar(
|
|
left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer),
|
|
center: new Text('PageableList'),
|
|
right: [
|
|
new Text(scrollDirection == ScrollDirection.horizontal ? "horizontal" : "vertical")
|
|
]
|
|
);
|
|
}
|
|
|
|
Widget buildBody(BuildContext context) {
|
|
Widget list = new PageableList<CardModel>(
|
|
items: cardModels,
|
|
itemsWrap: itemsWrap,
|
|
itemBuilder: buildCard,
|
|
scrollDirection: scrollDirection,
|
|
itemExtent: (scrollDirection == ScrollDirection.vertical)
|
|
? pageSize.height
|
|
: pageSize.width
|
|
);
|
|
return new SizeObserver(
|
|
callback: updatePageSize,
|
|
child: new Container(
|
|
child: list,
|
|
decoration: new BoxDecoration(backgroundColor: Theme.of(context).primarySwatch[50])
|
|
)
|
|
);
|
|
}
|
|
|
|
Widget build(BuildContext context) {
|
|
return new IconTheme(
|
|
data: const IconThemeData(color: IconThemeColor.white),
|
|
child: new Scaffold(
|
|
toolbar: buildToolBar(),
|
|
body: buildBody(context)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
runApp(new App(
|
|
title: 'PageableList',
|
|
theme: new ThemeData(
|
|
brightness: ThemeBrightness.light,
|
|
primarySwatch: Colors.blue,
|
|
accentColor: Colors.redAccent[200]
|
|
),
|
|
routes: {
|
|
'/': (NavigatorState navigator, Route route) => new PageableListApp(navigator: navigator),
|
|
}
|
|
));
|
|
}
|