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

Rather than use a Center widget, center the title using AppBar's centerTitle property. This ensures the title is horizontally centred with respect to the screen rather than centred in the space between the leading and trailing app bar widgets, which are asymmetrical in Shrine.
151 lines
4.6 KiB
Dart
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<Null>(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
|
|
)
|
|
);
|
|
}
|
|
}
|