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> { ...@@ -38,7 +38,7 @@ class CardCollectionState extends State<CardCollection> {
List<CardModel> _cardModels; List<CardModel> _cardModels;
DismissDirection _dismissDirection = DismissDirection.horizontal; DismissDirection _dismissDirection = DismissDirection.horizontal;
TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center); TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center);
bool _editable = true; bool _editable = false;
bool _snapToCenter = false; bool _snapToCenter = false;
bool _fixedSizeCards = false; bool _fixedSizeCards = false;
bool _sunshine = false; bool _sunshine = false;
...@@ -268,10 +268,16 @@ class CardCollectionState extends State<CardCollection> { ...@@ -268,10 +268,16 @@ class CardCollectionState extends State<CardCollection> {
Widget buildToolBar() { Widget buildToolBar() {
return new ToolBar( return new ToolBar(
left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer), left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer),
center: new Text('Swipe Away'),
right: <Widget>[ right: <Widget>[
new Text(_dismissDirectionText(_dismissDirection)) 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; ...@@ -14,6 +14,7 @@ const double kStatusBarHeight = 50.0;
// Mobile Portrait: 56dp // Mobile Portrait: 56dp
// Tablet/Desktop: 64dp // Tablet/Desktop: 64dp
const double kToolBarHeight = 56.0; const double kToolBarHeight = 56.0;
const double kExtendedToolBarHeight = 128.0;
const double kSnackBarHeight = 52.0; const double kSnackBarHeight = 52.0;
// https://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing // https://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
......
...@@ -218,7 +218,6 @@ class DropdownButton<T> extends StatelessComponent { ...@@ -218,7 +218,6 @@ class DropdownButton<T> extends StatelessComponent {
return new GestureDetector( return new GestureDetector(
child: new Container( child: new Container(
decoration: new BoxDecoration(border: _kDropdownUnderline), decoration: new BoxDecoration(border: _kDropdownUnderline),
child: new IntrinsicWidth(
child: new Row(<Widget>[ child: new Row(<Widget>[
new IndexedStack(items, new IndexedStack(items,
key: indexedStackKey, key: indexedStackKey,
...@@ -229,7 +228,8 @@ class DropdownButton<T> extends StatelessComponent { ...@@ -229,7 +228,8 @@ class DropdownButton<T> extends StatelessComponent {
child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36), child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36),
padding: const EdgeDims.only(top: 6.0) padding: const EdgeDims.only(top: 6.0)
) )
]) ],
justifyContent: FlexJustifyContent.collapse
) )
), ),
onTap: () { onTap: () {
......
...@@ -4,92 +4,88 @@ ...@@ -4,92 +4,88 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'constants.dart'; import 'constants.dart';
import 'material.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 { class Scaffold extends StatelessComponent {
Scaffold({ Scaffold({
Key key, Key key,
this.body, this.body,
this.statusBar,
this.toolBar, this.toolBar,
this.snackBar, this.snackBar,
this.floatingActionButton this.floatingActionButton
}) : super(key: key); }) : super(key: key);
final Widget body; final Widget body;
final Widget statusBar; final ToolBar toolBar;
final Widget toolBar;
final Widget snackBar; final Widget snackBar;
final Widget floatingActionButton; final Widget floatingActionButton;
Widget build(BuildContext context) { Widget build(BuildContext context) {
double toolBarHeight = 0.0; final ToolBar paddedToolBar = toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top));
if (toolBar != null) final Widget materialBody = body != null ? new Material(child: body) : null;
toolBarHeight = kToolBarHeight + ui.window.padding.top; Widget toolBarAndBody;
if (paddedToolBar != null && materialBody != null)
double statusBarHeight = 0.0; toolBarAndBody = new CustomMultiChildLayout(<Widget>[materialBody, paddedToolBar],
if (statusBar != null) delegate: _toolBarAndBodyLayout
statusBarHeight = kStatusBarHeight; );
else
List<Widget> children = <Widget>[]; toolBarAndBody = paddedToolBar ?? materialBody;
if (body != null) { final List<Widget> bottomColumnChildren = <Widget>[];
children.add(new Positioned(
top: toolBarHeight, right: 0.0, bottom: statusBarHeight, left: 0.0, if (floatingActionButton != null)
child: new Material( bottomColumnChildren.add(new Padding(
child: body
)
));
}
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
)
));
}
if (snackBar != null || floatingActionButton != null) {
List<Widget> floatingChildren = <Widget>[];
if (floatingActionButton != null) {
floatingChildren.add(new Padding(
// TODO(eseidel): These change based on device size! // TODO(eseidel): These change based on device size!
padding: const EdgeDims.only(right: 16.0, bottom: 16.0), padding: const EdgeDims.only(right: 16.0, bottom: 16.0),
child: floatingActionButton child: floatingActionButton
)); ));
}
// TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568 // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568
if (snackBar != null) { if (snackBar != null) {
floatingChildren.add(new ConstrainedBox( bottomColumnChildren.add(new ConstrainedBox(
constraints: const BoxConstraints(maxHeight: kSnackBarHeight), constraints: const BoxConstraints(maxHeight: kSnackBarHeight),
child: snackBar child: snackBar
)); ));
} }
children.add(new Positioned( final List<Widget> stackChildren = <Widget>[toolBarAndBody];
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 { ...@@ -17,17 +17,35 @@ class ToolBar extends StatelessComponent {
this.left, this.left,
this.center, this.center,
this.right, this.right,
this.bottom,
this.level: 2, this.level: 2,
this.backgroundColor, this.backgroundColor,
this.textTheme this.textTheme,
this.padding: EdgeDims.zero
}) : super(key: key); }) : super(key: key);
final Widget left; final Widget left;
final Widget center; final Widget center;
final List<Widget> right; final List<Widget> right;
final Widget bottom;
final int level; final int level;
final Color backgroundColor; final Color backgroundColor;
final TextTheme textTheme; 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) { Widget build(BuildContext context) {
Color color = backgroundColor; Color color = backgroundColor;
...@@ -62,6 +80,16 @@ class ToolBar extends StatelessComponent { ...@@ -62,6 +80,16 @@ class ToolBar extends StatelessComponent {
if (right != null) if (right != null)
children.addAll(right); 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( Widget content = new AnimatedContainer(
duration: kThemeChangeDuration, duration: kThemeChangeDuration,
padding: new EdgeDims.symmetric(horizontal: 8.0), padding: new EdgeDims.symmetric(horizontal: 8.0),
...@@ -71,14 +99,7 @@ class ToolBar extends StatelessComponent { ...@@ -71,14 +99,7 @@ class ToolBar extends StatelessComponent {
), ),
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: sideStyle, style: sideStyle,
child: new Column(<Widget>[ child: new Container(padding: padding, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse))
new Container(
child: new Row(children),
height: kToolBarHeight
),
],
justifyContent: FlexJustifyContent.end
)
) )
); );
......
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