Added menu dividers
This commit is contained in:
parent
52a24840cd
commit
d8eaac42fb
@ -111,7 +111,7 @@ class MenuDemoState extends State<MenuDemo> {
|
||||
primary: new Text('An item with a sectioned menu'),
|
||||
right: new PopupMenuButton<String>(
|
||||
onSelected: showMenuSelection,
|
||||
items: <PopupMenuItem>[
|
||||
items: <PopupMenuEntry<String>>[
|
||||
new PopupMenuItem(
|
||||
value: 'Preview',
|
||||
child: new ListItem(
|
||||
@ -128,12 +128,12 @@ class MenuDemoState extends State<MenuDemo> {
|
||||
),
|
||||
new PopupMenuItem(
|
||||
value: 'Get Link',
|
||||
hasDivider: true,
|
||||
child: new ListItem(
|
||||
left: new Icon(icon: 'content/link'),
|
||||
primary: new Text('Get Link')
|
||||
)
|
||||
),
|
||||
new PopupMenuDivider(),
|
||||
new PopupMenuItem(
|
||||
value: 'Remove',
|
||||
child: new ListItem(
|
||||
|
@ -56,7 +56,7 @@ class GalleryDrawer extends StatelessComponent {
|
||||
]
|
||||
)
|
||||
),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
new DrawerItem(
|
||||
icon: 'action/hourglass_empty',
|
||||
selected: timeDilation != 1.0,
|
||||
|
@ -169,7 +169,7 @@ class StockHomeState extends State<StockHome> {
|
||||
},
|
||||
child: new Text('Dump App to Console')
|
||||
),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
new DrawerItem(
|
||||
icon: 'action/thumb_up',
|
||||
onPressed: () => _handleStockModeChange(StockMode.optimistic),
|
||||
@ -190,7 +190,7 @@ class StockHomeState extends State<StockHome> {
|
||||
]
|
||||
)
|
||||
),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
new DrawerItem(
|
||||
icon: 'action/settings',
|
||||
onPressed: _handleShowSettings,
|
||||
|
@ -128,20 +128,20 @@ class CardCollectionState extends State<CardCollection> {
|
||||
buildDrawerCheckbox("Fixed size cards", _fixedSizeCards, _toggleFixedSizeCards),
|
||||
buildDrawerCheckbox("Let the sun shine", _sunshine, _toggleSunshine),
|
||||
buildDrawerCheckbox("Vary font sizes", _varyFontSizes, _toggleVaryFontSizes, enabled: !_editable),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
buildDrawerColorRadioItem("Deep Purple", Colors.deepPurple, _primaryColor, _selectColor),
|
||||
buildDrawerColorRadioItem("Green", Colors.green, _primaryColor, _selectColor),
|
||||
buildDrawerColorRadioItem("Amber", Colors.amber, _primaryColor, _selectColor),
|
||||
buildDrawerColorRadioItem("Teal", Colors.teal, _primaryColor, _selectColor),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: 'action/code'),
|
||||
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_back'),
|
||||
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_forward'),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: 'editor/format_align_left', enabled: !_editable),
|
||||
buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: 'editor/format_align_center', enabled: !_editable),
|
||||
buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: 'editor/format_align_right', enabled: !_editable),
|
||||
new DrawerDivider(),
|
||||
new Divider(),
|
||||
new DrawerItem(
|
||||
icon: 'device/dvr',
|
||||
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
|
||||
|
@ -20,9 +20,9 @@ export 'src/material/date_picker.dart';
|
||||
export 'src/material/date_picker_dialog.dart';
|
||||
export 'src/material/dialog.dart';
|
||||
export 'src/material/drawer.dart';
|
||||
export 'src/material/drawer_divider.dart';
|
||||
export 'src/material/drawer_header.dart';
|
||||
export 'src/material/drawer_item.dart';
|
||||
export 'src/material/divider.dart';
|
||||
export 'src/material/dropdown.dart';
|
||||
export 'src/material/flat_button.dart';
|
||||
export 'src/material/flexible_space_bar.dart';
|
||||
|
34
packages/flutter/lib/src/material/divider.dart
Normal file
34
packages/flutter/lib/src/material/divider.dart
Normal file
@ -0,0 +1,34 @@
|
||||
// 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:flutter/widgets.dart';
|
||||
|
||||
import 'theme.dart';
|
||||
|
||||
class Divider extends StatelessComponent {
|
||||
Divider({ Key key, this.height: 16.0, this.indent: 0.0, this.color }) : super(key: key) {
|
||||
assert(height >= 1.0);
|
||||
}
|
||||
|
||||
final double height;
|
||||
final double indent;
|
||||
final Color color;
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
final double bottom = (height ~/ 2.0).toDouble();
|
||||
return new Container(
|
||||
height: 0.0,
|
||||
margin: new EdgeDims.only(
|
||||
top: height - bottom - 1.0,
|
||||
left: indent,
|
||||
bottom: bottom
|
||||
),
|
||||
decoration: new BoxDecoration(
|
||||
border: new Border(
|
||||
bottom: new BorderSide(color: color ?? Theme.of(context).dividerColor)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// 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:flutter/widgets.dart';
|
||||
|
||||
import 'theme.dart';
|
||||
|
||||
class DrawerDivider extends StatelessComponent {
|
||||
const DrawerDivider({ Key key }) : super(key: key);
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return new Container(
|
||||
height: 0.0,
|
||||
decoration: new BoxDecoration(
|
||||
border: new Border(
|
||||
bottom: new BorderSide(
|
||||
color: Theme.of(context).dividerColor
|
||||
)
|
||||
)
|
||||
),
|
||||
margin: const EdgeDims.symmetric(vertical: 8.0)
|
||||
);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'divider.dart';
|
||||
import 'icon.dart';
|
||||
import 'icon_button.dart';
|
||||
import 'icon_theme.dart';
|
||||
@ -26,20 +27,36 @@ const double _kMenuVerticalPadding = 8.0;
|
||||
const double _kMenuWidthStep = 56.0;
|
||||
const double _kMenuScreenPadding = 8.0;
|
||||
|
||||
class PopupMenuItem<T> extends StatelessComponent {
|
||||
abstract class PopupMenuEntry<T> extends StatelessComponent {
|
||||
PopupMenuEntry({ Key key }) : super(key: key);
|
||||
|
||||
double get height;
|
||||
T get value => null;
|
||||
bool get enabled => true;
|
||||
}
|
||||
|
||||
class PopupMenuDivider extends PopupMenuEntry<dynamic> {
|
||||
PopupMenuDivider({ Key key, this.height: 16.0 }) : super(key: key);
|
||||
|
||||
final double height;
|
||||
|
||||
Widget build(BuildContext context) => new Divider(height: height);
|
||||
}
|
||||
|
||||
class PopupMenuItem<T> extends PopupMenuEntry<T> {
|
||||
PopupMenuItem({
|
||||
Key key,
|
||||
this.value,
|
||||
this.enabled: true,
|
||||
this.hasDivider: false,
|
||||
this.child
|
||||
}) : super(key: key);
|
||||
|
||||
final T value;
|
||||
final bool enabled;
|
||||
final bool hasDivider;
|
||||
final Widget child;
|
||||
|
||||
double get height => _kMenuItemHeight;
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
TextStyle style = theme.text.subhead;
|
||||
@ -49,7 +66,7 @@ class PopupMenuItem<T> extends StatelessComponent {
|
||||
Widget item = new DefaultTextStyle(
|
||||
style: style,
|
||||
child: new Baseline(
|
||||
baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
|
||||
baseline: height - _kBaselineOffsetFromBottom,
|
||||
child: child
|
||||
)
|
||||
);
|
||||
@ -63,11 +80,8 @@ class PopupMenuItem<T> extends StatelessComponent {
|
||||
|
||||
return new MergeSemantics(
|
||||
child: new Container(
|
||||
height: _kMenuItemHeight,
|
||||
height: height,
|
||||
padding: const EdgeDims.symmetric(horizontal: _kMenuHorizontalPadding),
|
||||
decoration: !hasDivider ? null : new BoxDecoration(
|
||||
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
|
||||
),
|
||||
child: item
|
||||
)
|
||||
);
|
||||
@ -172,10 +186,10 @@ class _PopupMenu<T> extends StatelessComponent {
|
||||
}
|
||||
|
||||
class _PopupMenuRouteLayout extends OneChildLayoutDelegate {
|
||||
_PopupMenuRouteLayout(this.position, this.selectedIndex);
|
||||
_PopupMenuRouteLayout(this.position, this.selectedItemOffset);
|
||||
|
||||
final ModalPosition position;
|
||||
final int selectedIndex;
|
||||
final double selectedItemOffset;
|
||||
|
||||
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||
return new BoxConstraints(
|
||||
@ -195,8 +209,8 @@ class _PopupMenuRouteLayout extends OneChildLayoutDelegate {
|
||||
double y = position?.top
|
||||
?? (position?.bottom != null ? size.height - (position.bottom - childSize.height) : _kMenuScreenPadding);
|
||||
|
||||
if (selectedIndex != -1)
|
||||
y -= (_kMenuItemHeight * selectedIndex) + _kMenuVerticalPadding + _kMenuItemHeight / 2.0;
|
||||
if (selectedItemOffset != null)
|
||||
y -= selectedItemOffset + _kMenuVerticalPadding + _kMenuItemHeight / 2.0;
|
||||
|
||||
if (x < _kMenuScreenPadding)
|
||||
x = _kMenuScreenPadding;
|
||||
@ -224,7 +238,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
||||
}) : super(completer: completer);
|
||||
|
||||
final ModalPosition position;
|
||||
final List<PopupMenuItem<T>> items;
|
||||
final List<PopupMenuEntry<T>> items;
|
||||
final dynamic initialValue;
|
||||
final int elevation;
|
||||
|
||||
@ -242,19 +256,20 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
||||
Color get barrierColor => null;
|
||||
|
||||
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
|
||||
int selectedIndex = -1;
|
||||
double selectedItemOffset = null;
|
||||
if (initialValue != null) {
|
||||
for (int i = 0; i < items.length; i++)
|
||||
if (initialValue == items[i].value) {
|
||||
selectedIndex = i;
|
||||
selectedItemOffset = 0.0;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (initialValue == items[i].value)
|
||||
break;
|
||||
}
|
||||
selectedItemOffset += items[i].height;
|
||||
}
|
||||
}
|
||||
final Size screenSize = MediaQuery.of(context).size;
|
||||
return new ConstrainedBox(
|
||||
constraints: new BoxConstraints(maxWidth: screenSize.width, maxHeight: screenSize.height),
|
||||
child: new CustomOneChildLayout(
|
||||
delegate: new _PopupMenuRouteLayout(position, selectedIndex),
|
||||
delegate: new _PopupMenuRouteLayout(position, selectedItemOffset),
|
||||
child: new _PopupMenu(route: this)
|
||||
)
|
||||
);
|
||||
@ -269,7 +284,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
||||
Future/*<T>*/ showMenu/*<T>*/({
|
||||
BuildContext context,
|
||||
ModalPosition position,
|
||||
List<PopupMenuItem/*<T>*/> items,
|
||||
List<PopupMenuEntry/*<T>*/> items,
|
||||
dynamic/*=T*/ initialValue,
|
||||
int elevation: 8
|
||||
}) {
|
||||
@ -305,7 +320,7 @@ class PopupMenuButton<T> extends StatefulComponent {
|
||||
this.child
|
||||
}) : super(key: key);
|
||||
|
||||
final List<PopupMenuItem<T>> items;
|
||||
final List<PopupMenuEntry<T>> items;
|
||||
final T initialValue;
|
||||
final PopupMenuItemSelected<T> onSelected;
|
||||
final String tooltip;
|
||||
|
Loading…
x
Reference in New Issue
Block a user