flutter/examples/flutter_gallery/lib/demo/shrine/shrine_page.dart
Ian Hickson aba0379dcc
Clean up the existing Navigator API. (#15718)
This is not a grand refactor yet, it's just cleaning up what we have
already, so that people who keep using this API (e.g. dialogs) have
something coherent to deal with.

The major changes are that Navigator and NavigatorState have the same
API now, that most of the examples use `<void>` instead of `<Null>`,
that the navigator observer can see replaces, and that the `settings`
is moved from ModalRoute to Route. I also cleaned up some of the API
documentation.
2018-03-22 13:21:07 -07:00

151 lines
4.6 KiB
Dart

// Copyright 2016 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:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'shrine_theme.dart';
import 'shrine_types.dart';
enum ShrineAction {
sortByPrice,
sortByProduct,
emptyCart
}
class ShrinePage extends StatefulWidget {
const ShrinePage({
Key key,
@required this.scaffoldKey,
@required this.body,
this.floatingActionButton,
this.products,
this.shoppingCart
}) : assert(body != null),
assert(scaffoldKey != null),
super(key: key);
final GlobalKey<ScaffoldState> scaffoldKey;
final Widget body;
final Widget floatingActionButton;
final List<Product> products;
final Map<Product, Order> shoppingCart;
@override
ShrinePageState createState() => new ShrinePageState();
}
/// Defines the Scaffold, AppBar, etc that the demo pages have in common.
class ShrinePageState extends State<ShrinePage> {
double _appBarElevation = 0.0;
bool _handleScrollNotification(ScrollNotification notification) {
final double elevation = notification.metrics.extentBefore <= 0.0 ? 0.0 : 1.0;
if (elevation != _appBarElevation) {
setState(() {
_appBarElevation = elevation;
});
}
return false;
}
void _showShoppingCart() {
showModalBottomSheet<void>(context: context, builder: (BuildContext context) {
if (widget.shoppingCart.isEmpty) {
return const Padding(
padding: const EdgeInsets.all(24.0),
child: const Text('The shopping cart is empty')
);
}
return new ListView(
padding: kMaterialListPadding,
children: widget.shoppingCart.values.map((Order order) {
return new ListTile(
title: new Text(order.product.name),
leading: new Text('${order.quantity}'),
subtitle: new Text(order.product.vendor.name)
);
}).toList(),
);
});
}
void _sortByPrice() {
widget.products.sort((Product a, Product b) => a.price.compareTo(b.price));
}
void _sortByProduct() {
widget.products.sort((Product a, Product b) => a.name.compareTo(b.name));
}
void _emptyCart() {
widget.shoppingCart.clear();
widget.scaffoldKey.currentState.showSnackBar(const SnackBar(content: const Text('Shopping cart is empty')));
}
@override
Widget build(BuildContext context) {
final ShrineTheme theme = ShrineTheme.of(context);
return new Scaffold(
key: widget.scaffoldKey,
appBar: new AppBar(
elevation: _appBarElevation,
backgroundColor: theme.appBarBackgroundColor,
iconTheme: Theme.of(context).iconTheme,
brightness: Brightness.light,
flexibleSpace: new Container(
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(color: theme.dividerColor)
)
)
),
title: new Text('SHRINE', style: ShrineTheme.of(context).appBarTitleStyle),
centerTitle: true,
actions: <Widget>[
new IconButton(
icon: const Icon(Icons.shopping_cart),
tooltip: 'Shopping cart',
onPressed: _showShoppingCart
),
new PopupMenuButton<ShrineAction>(
itemBuilder: (BuildContext context) => <PopupMenuItem<ShrineAction>>[
const PopupMenuItem<ShrineAction>(
value: ShrineAction.sortByPrice,
child: const Text('Sort by price')
),
const PopupMenuItem<ShrineAction>(
value: ShrineAction.sortByProduct,
child: const Text('Sort by product')
),
const PopupMenuItem<ShrineAction>(
value: ShrineAction.emptyCart,
child: const Text('Empty shopping cart')
)
],
onSelected: (ShrineAction action) {
switch (action) {
case ShrineAction.sortByPrice:
setState(_sortByPrice);
break;
case ShrineAction.sortByProduct:
setState(_sortByProduct);
break;
case ShrineAction.emptyCart:
setState(_emptyCart);
break;
}
}
)
]
),
floatingActionButton: widget.floatingActionButton,
body: new NotificationListener<ScrollNotification>(
onNotification: _handleScrollNotification,
child: widget.body
)
);
}
}