Commit 218bbdc1 authored by Hans Muller's avatar Hans Muller

Merge pull request #1907 from HansMuller/toolbar_bottom

Add support for "extended height" toolbars - ToolBar bottom

Added a Widget-valued bottom ToolBar property. If set the bottom widget appears below the normal toolbar.

Removed the kToolBarHeight hardwiring from Scaffold.

Updated the "swipe away" demo to use an extended height toolbar.
parents 4521fd24 56ccfc4e
......@@ -38,7 +38,7 @@ class CardCollectionState extends State<CardCollection> {
List<CardModel> _cardModels;
DismissDirection _dismissDirection = DismissDirection.horizontal;
TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center);
bool _editable = true;
bool _editable = false;
bool _snapToCenter = false;
bool _fixedSizeCards = false;
bool _sunshine = false;
......@@ -268,10 +268,16 @@ class CardCollectionState extends State<CardCollection> {
Widget buildToolBar() {
return new ToolBar(
left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer),
center: new Text('Swipe Away'),
right: <Widget>[
new Text(_dismissDirectionText(_dismissDirection))
]
],
bottom: new Padding(
padding: const EdgeDims.only(left: 72.0),
child: new Align(
alignment: const FractionalOffset(0.0, 0.5),
child: new Text('Swipe Away: ${_cardModels.length}')
)
)
);
}
......
......@@ -14,6 +14,7 @@ const double kStatusBarHeight = 50.0;
// Mobile Portrait: 56dp
// Tablet/Desktop: 64dp
const double kToolBarHeight = 56.0;
const double kExtendedToolBarHeight = 128.0;
const double kSnackBarHeight = 52.0;
// https://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
......
......@@ -218,18 +218,18 @@ class DropdownButton<T> extends StatelessComponent {
return new GestureDetector(
child: new Container(
decoration: new BoxDecoration(border: _kDropdownUnderline),
child: new IntrinsicWidth(
child: new Row(<Widget>[
new IndexedStack(items,
key: indexedStackKey,
index: selectedIndex,
alignment: const FractionalOffset(0.5, 0.0)
),
new Container(
child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36),
padding: const EdgeDims.only(top: 6.0)
)
])
child: new Row(<Widget>[
new IndexedStack(items,
key: indexedStackKey,
index: selectedIndex,
alignment: const FractionalOffset(0.5, 0.0)
),
new Container(
child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36),
padding: const EdgeDims.only(top: 6.0)
)
],
justifyContent: FlexJustifyContent.collapse
)
),
onTap: () {
......
......@@ -4,92 +4,88 @@
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'material.dart';
import 'tool_bar.dart';
const int _kBodyIndex = 0;
const int _kToolBarIndex = 1;
// This layout has the same effect as putting the toolbar and body in a column
// and making the body flexible. What's different is that in this case the
// toolbar appears -after- the body in the stacking order, so the toolbar's
// shadow is drawn on top of the body.
class _ToolBarAndBodyLayout extends MultiChildLayoutDelegate {
void performLayout(Size size, BoxConstraints constraints, int childCount) {
assert(childCount == 2);
final BoxConstraints toolBarConstraints = constraints.loosen().tightenWidth(size.width);
final Size toolBarSize = layoutChild(_kToolBarIndex, toolBarConstraints);
final double bodyHeight = size.height - toolBarSize.height;
final BoxConstraints bodyConstraints = toolBarConstraints.tightenHeight(bodyHeight);
layoutChild(_kBodyIndex, bodyConstraints);
positionChild(_kToolBarIndex, Point.origin);
positionChild(_kBodyIndex, new Point(0.0, toolBarSize.height));
}
}
final _ToolBarAndBodyLayout _toolBarAndBodyLayout = new _ToolBarAndBodyLayout();
class Scaffold extends StatelessComponent {
Scaffold({
Key key,
this.body,
this.statusBar,
this.toolBar,
this.snackBar,
this.floatingActionButton
}) : super(key: key);
final Widget body;
final Widget statusBar;
final Widget toolBar;
final ToolBar toolBar;
final Widget snackBar;
final Widget floatingActionButton;
Widget build(BuildContext context) {
double toolBarHeight = 0.0;
if (toolBar != null)
toolBarHeight = kToolBarHeight + ui.window.padding.top;
double statusBarHeight = 0.0;
if (statusBar != null)
statusBarHeight = kStatusBarHeight;
List<Widget> children = <Widget>[];
if (body != null) {
children.add(new Positioned(
top: toolBarHeight, right: 0.0, bottom: statusBarHeight, left: 0.0,
child: new Material(
child: body
)
final ToolBar paddedToolBar = toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top));
final Widget materialBody = body != null ? new Material(child: body) : null;
Widget toolBarAndBody;
if (paddedToolBar != null && materialBody != null)
toolBarAndBody = new CustomMultiChildLayout(<Widget>[materialBody, paddedToolBar],
delegate: _toolBarAndBodyLayout
);
else
toolBarAndBody = paddedToolBar ?? materialBody;
final List<Widget> bottomColumnChildren = <Widget>[];
if (floatingActionButton != null)
bottomColumnChildren.add(new Padding(
// TODO(eseidel): These change based on device size!
padding: const EdgeDims.only(right: 16.0, bottom: 16.0),
child: floatingActionButton
));
}
if (statusBar != null) {
children.add(new Positioned(
right: 0.0, bottom: 0.0, left: 0.0,
child: new SizedBox(
height: statusBarHeight,
child: statusBar
)
));
}
if (toolBar != null) {
children.add(new Positioned(
top: 0.0, right: 0.0, left: 0.0,
child: new SizedBox(
height: toolBarHeight,
child: toolBar
)
// TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
if (snackBar != null) {
bottomColumnChildren.add(new ConstrainedBox(
constraints: const BoxConstraints(maxHeight: kSnackBarHeight),
child: snackBar
));
}
if (snackBar != null || floatingActionButton != null) {
List<Widget> floatingChildren = <Widget>[];
if (floatingActionButton != null) {
floatingChildren.add(new Padding(
// TODO(eseidel): These change based on device size!
padding: const EdgeDims.only(right: 16.0, bottom: 16.0),
child: floatingActionButton
));
}
// TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
if (snackBar != null) {
floatingChildren.add(new ConstrainedBox(
constraints: const BoxConstraints(maxHeight: kSnackBarHeight),
child: snackBar
));
}
final List<Widget> stackChildren = <Widget>[toolBarAndBody];
children.add(new Positioned(
right: 0.0, bottom: statusBarHeight, left: 0.0,
child: new Column(floatingChildren, alignItems: FlexAlignItems.end)
if (bottomColumnChildren.length > 0) {
stackChildren.add(new Positioned(
right: 0.0,
left: 0.0,
bottom: 0.0,
child: new Column(bottomColumnChildren, alignItems: FlexAlignItems.end)
));
}
return new Stack(children);
return new Stack(stackChildren);
}
}
......@@ -17,17 +17,35 @@ class ToolBar extends StatelessComponent {
this.left,
this.center,
this.right,
this.bottom,
this.level: 2,
this.backgroundColor,
this.textTheme
this.textTheme,
this.padding: EdgeDims.zero
}) : super(key: key);
final Widget left;
final Widget center;
final List<Widget> right;
final Widget bottom;
final int level;
final Color backgroundColor;
final TextTheme textTheme;
final EdgeDims padding;
ToolBar withPadding(EdgeDims newPadding) {
return new ToolBar(
key: key,
left: left,
center: center,
right: right,
bottom: bottom,
level: level,
backgroundColor: backgroundColor,
textTheme: textTheme,
padding: newPadding
);
}
Widget build(BuildContext context) {
Color color = backgroundColor;
......@@ -62,6 +80,16 @@ class ToolBar extends StatelessComponent {
if (right != null)
children.addAll(right);
final List<Widget> columnChildren = <Widget>[
new Container(height: kToolBarHeight, child: new Row(children))
];
if (bottom != null)
columnChildren.add(new DefaultTextStyle(
style: centerStyle,
child: new Container(height: kExtendedToolBarHeight - kToolBarHeight, child: bottom)
));
Widget content = new AnimatedContainer(
duration: kThemeChangeDuration,
padding: new EdgeDims.symmetric(horizontal: 8.0),
......@@ -71,14 +99,7 @@ class ToolBar extends StatelessComponent {
),
child: new DefaultTextStyle(
style: sideStyle,
child: new Column(<Widget>[
new Container(
child: new Row(children),
height: kToolBarHeight
),
],
justifyContent: FlexJustifyContent.end
)
child: new Container(padding: padding, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse))
)
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment