Commit 8edeecbc authored by Hans Muller's avatar Hans Muller

Merge pull request #2216 from HansMuller/stocks_demo

Add CheckedPopupMenuitem, update the Stocks demo
parents 29e55735 3d377305
...@@ -21,7 +21,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -21,7 +21,7 @@ class ListDemoState extends State<ListDemo> {
ScaffoldFeatureController _bottomSheet; ScaffoldFeatureController _bottomSheet;
ListDemoItemSize _itemSize = ListDemoItemSize.threeLine; ListDemoItemSize _itemSize = ListDemoItemSize.threeLine;
bool _isDense = true; bool _dense = true;
bool _showAvatar = true; bool _showAvatar = true;
bool _showIcon = false; bool _showIcon = false;
bool _reverseSort = false; bool _reverseSort = false;
...@@ -47,7 +47,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -47,7 +47,7 @@ class ListDemoState extends State<ListDemo> {
alignItems: FlexAlignItems.stretch, alignItems: FlexAlignItems.stretch,
children: <Widget>[ children: <Widget>[
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('One-line'), primary: new Text('One-line'),
right: new Radio<ListDemoItemSize>( right: new Radio<ListDemoItemSize>(
value: ListDemoItemSize.oneLine, value: ListDemoItemSize.oneLine,
...@@ -56,7 +56,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -56,7 +56,7 @@ class ListDemoState extends State<ListDemo> {
) )
), ),
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('Two-line'), primary: new Text('Two-line'),
right: new Radio<ListDemoItemSize>( right: new Radio<ListDemoItemSize>(
value: ListDemoItemSize.twoLine, value: ListDemoItemSize.twoLine,
...@@ -65,7 +65,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -65,7 +65,7 @@ class ListDemoState extends State<ListDemo> {
) )
), ),
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('Three-line'), primary: new Text('Three-line'),
right: new Radio<ListDemoItemSize>( right: new Radio<ListDemoItemSize>(
value: ListDemoItemSize.threeLine, value: ListDemoItemSize.threeLine,
...@@ -74,7 +74,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -74,7 +74,7 @@ class ListDemoState extends State<ListDemo> {
) )
), ),
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('Show Avatar'), primary: new Text('Show Avatar'),
right: new Checkbox( right: new Checkbox(
value: _showAvatar, value: _showAvatar,
...@@ -87,7 +87,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -87,7 +87,7 @@ class ListDemoState extends State<ListDemo> {
) )
), ),
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('Show Icon'), primary: new Text('Show Icon'),
right: new Checkbox( right: new Checkbox(
value: _showIcon, value: _showIcon,
...@@ -100,13 +100,13 @@ class ListDemoState extends State<ListDemo> { ...@@ -100,13 +100,13 @@ class ListDemoState extends State<ListDemo> {
) )
), ),
new ListItem( new ListItem(
isDense: true, dense: true,
primary: new Text('Dense Layout'), primary: new Text('Dense Layout'),
right: new Checkbox( right: new Checkbox(
value: _isDense, value: _dense,
onChanged: (bool value) { onChanged: (bool value) {
setState(() { setState(() {
_isDense = value; _dense = value;
}); });
_bottomSheet?.setState(() { }); _bottomSheet?.setState(() { });
} }
...@@ -131,7 +131,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -131,7 +131,7 @@ class ListDemoState extends State<ListDemo> {
} }
return new ListItem( return new ListItem(
isThreeLine: _itemSize == ListDemoItemSize.threeLine, isThreeLine: _itemSize == ListDemoItemSize.threeLine,
isDense: _isDense, dense: _dense,
left: _showAvatar ? new CircleAvatar(child: new Text(item)) : null, left: _showAvatar ? new CircleAvatar(child: new Text(item)) : null,
primary: new Text('This item represents $item'), primary: new Text('This item represents $item'),
secondary: secondary, secondary: secondary,
...@@ -140,7 +140,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -140,7 +140,7 @@ class ListDemoState extends State<ListDemo> {
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
final String layoutText = _isDense ? " \u2013 Dense" : ""; final String layoutText = _dense ? " \u2013 Dense" : "";
String itemSizeText; String itemSizeText;
switch(_itemSize) { switch(_itemSize) {
case ListDemoItemSize.oneLine: case ListDemoItemSize.oneLine:
...@@ -176,7 +176,7 @@ class ListDemoState extends State<ListDemo> { ...@@ -176,7 +176,7 @@ class ListDemoState extends State<ListDemo> {
] ]
), ),
body: new Block( body: new Block(
padding: new EdgeDims.all(_isDense ? 4.0 : 8.0), padding: new EdgeDims.all(_dense ? 4.0 : 8.0),
children: items.map((String item) => buildListItem(context, item)).toList() children: items.map((String item) => buildListItem(context, item)).toList()
) )
); );
......
...@@ -94,7 +94,7 @@ class MenuDemoState extends State<MenuDemo> { ...@@ -94,7 +94,7 @@ class MenuDemoState extends State<MenuDemo> {
child: new Text('Context menu item one') child: new Text('Context menu item one')
), ),
new PopupMenuItem( new PopupMenuItem(
disabled: true, enabled: false,
child: new Text('A disabled menu item') child: new Text('A disabled menu item')
), ),
new PopupMenuItem( new PopupMenuItem(
...@@ -176,34 +176,26 @@ class MenuDemoState extends State<MenuDemo> { ...@@ -176,34 +176,26 @@ class MenuDemoState extends State<MenuDemo> {
right: new PopupMenuButton<String>( right: new PopupMenuButton<String>(
onSelected: showCheckedMenuSelections, onSelected: showCheckedMenuSelections,
items: <PopupMenuItem>[ items: <PopupMenuItem>[
new PopupMenuItem( new CheckedPopupMenuItem(
value: _checkedValue1, value: _checkedValue1,
child: new ListItem( checked: isChecked(_checkedValue1),
left: new Icon(icon: isChecked(_checkedValue1) ? 'action/done' : null), child: new Text(_checkedValue1)
primary: new Text(_checkedValue1)
)
), ),
new PopupMenuItem( new CheckedPopupMenuItem(
value: _checkedValue2, enabled: false,
child: new ListItem( checked: isChecked(_checkedValue2),
left: new Icon(icon: isChecked(_checkedValue2) ? 'action/done' : null), child: new Text(_checkedValue2)
primary: new Text(_checkedValue2)
)
), ),
new PopupMenuItem( new CheckedPopupMenuItem(
value: _checkedValue3, value: _checkedValue3,
child: new ListItem( checked: isChecked(_checkedValue3),
left: new Icon(icon: isChecked(_checkedValue3) ? 'action/done' : null), child: new Text(_checkedValue3)
primary: new Text(_checkedValue3)
)
), ),
new PopupMenuItem( new CheckedPopupMenuItem(
value: _checkedValue4, value: _checkedValue4,
child: new ListItem( checked: isChecked(_checkedValue4),
left: new Icon(icon: isChecked(_checkedValue4) ? 'action/done' : null), child: new Text(_checkedValue4)
primary: new Text(_checkedValue4) )
)
),
] ]
) )
) )
......
...@@ -6,6 +6,7 @@ material-design-icons: ...@@ -6,6 +6,7 @@ material-design-icons:
- name: action/account_balance - name: action/account_balance
- name: action/assessment - name: action/assessment
- name: action/backup - name: action/backup
- name: action/done
- name: action/help - name: action/help
- name: action/picture_in_picture - name: action/picture_in_picture
- name: action/search - name: action/search
......
...@@ -6,18 +6,50 @@ import 'dart:collection'; ...@@ -6,18 +6,50 @@ import 'dart:collection';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show debugDumpRenderTree, debugDumpLayerTree, debugDumpSemanticsTree; import 'package:flutter/rendering.dart' show debugDumpRenderTree, debugDumpLayerTree, debugDumpSemanticsTree;
import 'package:flutter/scheduler.dart' show timeDilation;
import 'stock_data.dart'; import 'stock_data.dart';
import 'stock_list.dart'; import 'stock_list.dart';
import 'stock_menu.dart';
import 'stock_strings.dart'; import 'stock_strings.dart';
import 'stock_symbol_viewer.dart'; import 'stock_symbol_viewer.dart';
import 'stock_types.dart'; import 'stock_types.dart';
typedef void ModeUpdater(StockMode mode); typedef void ModeUpdater(StockMode mode);
enum _StockMenuItem { autorefresh, refresh, speedUp, speedDown }
enum StockHomeTab { market, portfolio } enum StockHomeTab { market, portfolio }
class _NotImplementedDialog extends StatelessComponent {
Widget build(BuildContext context) {
return new Dialog(
title: new Text('Not Implemented'),
content: new Text('This feature has not yet been implemented.'),
actions: <Widget>[
new FlatButton(
child: new Row(
children: <Widget>[
new Icon(
icon: 'device/dvr',
size: IconSize.s18
),
new Container(
width: 8.0
),
new Text('DUMP APP TO CONSOLE'),
]
),
onPressed: () { debugDumpApp(); }
),
new FlatButton(
child: new Text('OH WELL'),
onPressed: () {
Navigator.pop(context, false);
}
)
]
);
}
}
class StockHome extends StatefulComponent { class StockHome extends StatefulComponent {
const StockHome(this.stocks, this.symbols, this.configuration, this.updater); const StockHome(this.stocks, this.symbols, this.configuration, this.updater);
...@@ -34,6 +66,7 @@ class StockHomeState extends State<StockHome> { ...@@ -34,6 +66,7 @@ class StockHomeState extends State<StockHome> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool _isSearching = false; bool _isSearching = false;
InputValue _searchQuery = InputValue.empty; InputValue _searchQuery = InputValue.empty;
bool _autorefresh = false;
void _handleSearchBegin() { void _handleSearchBegin() {
ModalRoute.of(context).addLocalHistoryEntry(new LocalHistoryEntry( ModalRoute.of(context).addLocalHistoryEntry(new LocalHistoryEntry(
...@@ -59,24 +92,31 @@ class StockHomeState extends State<StockHome> { ...@@ -59,24 +92,31 @@ class StockHomeState extends State<StockHome> {
}); });
} }
bool _autorefresh = false;
void _handleAutorefreshChanged(bool value) {
setState(() {
_autorefresh = value;
});
}
void _handleStockModeChange(StockMode value) { void _handleStockModeChange(StockMode value) {
if (config.updater != null) if (config.updater != null)
config.updater(config.configuration.copyWith(stockMode: value)); config.updater(config.configuration.copyWith(stockMode: value));
} }
void _handleMenuShow() { void _handleStockMenu(BuildContext context, _StockMenuItem value) {
showStockMenu( switch(value) {
context: context, case _StockMenuItem.autorefresh:
autorefresh: _autorefresh, setState(() {
onAutorefreshChanged: _handleAutorefreshChanged _autorefresh = !_autorefresh;
); });
break;
case _StockMenuItem.refresh:
showDialog(
context: context,
child: new _NotImplementedDialog()
);
break;
case _StockMenuItem.speedUp:
timeDilation /= 5.0;
break;
case _StockMenuItem.speedDown:
timeDilation *= 5.0;
break;
}
} }
Widget _buildDrawer(BuildContext context) { Widget _buildDrawer(BuildContext context) {
...@@ -176,10 +216,27 @@ class StockHomeState extends State<StockHome> { ...@@ -176,10 +216,27 @@ class StockHomeState extends State<StockHome> {
onPressed: _handleSearchBegin, onPressed: _handleSearchBegin,
tooltip: 'Search' tooltip: 'Search'
), ),
new IconButton( new PopupMenuButton<_StockMenuItem>(
icon: "navigation/more_vert", onSelected: (_StockMenuItem value) { _handleStockMenu(context, value); },
onPressed: _handleMenuShow, items: <PopupMenuItem>[
tooltip: 'Show menu' new CheckedPopupMenuItem(
value: _StockMenuItem.autorefresh,
checked: _autorefresh,
child: new Text('Autorefresh')
),
new PopupMenuItem(
value: _StockMenuItem.refresh,
child: new Text('Refresh')
),
new PopupMenuItem(
value: _StockMenuItem.speedUp,
child: new Text('Increase animation speed')
),
new PopupMenuItem(
value: _StockMenuItem.speedDown,
child: new Text('Decrease animation speed')
)
]
) )
], ],
tabBar: new TabBar<StockHomeTab>( tabBar: new TabBar<StockHomeTab>(
......
// 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 'dart:async';
import 'dart:ui' as ui show window;
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
enum _MenuItems { autorefresh, autorefreshCheckbox, refresh, speedUp, speedDown }
const double _kMenuMargin = 16.0; // 24.0 on tablet
Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged<bool> onAutorefreshChanged }) async {
StateSetter autorefreshStateSetter;
switch (await showMenu(
context: context,
position: new ModalPosition(
right: ui.window.padding.right + _kMenuMargin,
top: ui.window.padding.top + _kMenuMargin
),
items: <PopupMenuItem>[
new PopupMenuItem(
value: _MenuItems.autorefresh,
child: new Row(
children: <Widget>[
new Flexible(child: new Text('Autorefresh')),
new StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
autorefreshStateSetter = setState;
return new Checkbox(
value: autorefresh,
onChanged: (bool value) {
setState(() {
autorefresh = value;
});
Navigator.pop(context, _MenuItems.autorefreshCheckbox);
}
);
}
)
]
)
),
new PopupMenuItem(
value: _MenuItems.refresh,
child: new Text('Refresh')
),
new PopupMenuItem(
value: _MenuItems.speedUp,
child: new Text('Increase animation speed')
),
new PopupMenuItem(
value: _MenuItems.speedDown,
child: new Text('Decrease animation speed')
),
]
)) {
case _MenuItems.autorefresh:
autorefreshStateSetter(() {
autorefresh = !autorefresh;
});
continue autorefreshNotify;
autorefreshNotify:
case _MenuItems.autorefreshCheckbox:
onAutorefreshChanged(autorefresh);
break;
case _MenuItems.speedUp:
timeDilation /= 5.0;
break;
case _MenuItems.speedDown:
timeDilation *= 5.0;
break;
case _MenuItems.refresh:
await showDialog(
context: context,
child: new Dialog(
title: new Text('Not Implemented'),
content: new Text('This feature has not yet been implemented.'),
actions: <Widget>[
new FlatButton(
child: new Row(
children: <Widget>[
new Icon(
icon: 'device/dvr',
size: IconSize.s18
),
new Container(
width: 8.0
),
new Text('DUMP APP TO CONSOLE'),
]
),
onPressed: () { debugDumpApp(); }
),
new FlatButton(
child: new Text('OH WELL'),
onPressed: () {
Navigator.pop(context, false);
}
),
]
)
);
break;
default:
// menu was canceled.
}
}
...@@ -11,7 +11,7 @@ import 'theme.dart'; ...@@ -11,7 +11,7 @@ import 'theme.dart';
/// Icons are defined with the [left] and [right] parameters. The first line of text /// Icons are defined with the [left] and [right] parameters. The first line of text
/// is not optional and is specified with [primary]. The value of [secondary] will /// is not optional and is specified with [primary]. The value of [secondary] will
/// occupy the space allocated for an aditional line of text, or two lines if /// occupy the space allocated for an aditional line of text, or two lines if
/// isThreeLine: true is specified. If isDense: true is specified then the overall /// isThreeLine: true is specified. If dense: true is specified then the overall
/// height of this list item and the size of the DefaultTextStyles that wrap /// height of this list item and the size of the DefaultTextStyles that wrap
/// the [primary] and [secondary] widget are reduced. /// the [primary] and [secondary] widget are reduced.
class ListItem extends StatelessComponent { class ListItem extends StatelessComponent {
...@@ -22,7 +22,8 @@ class ListItem extends StatelessComponent { ...@@ -22,7 +22,8 @@ class ListItem extends StatelessComponent {
this.secondary, this.secondary,
this.right, this.right,
this.isThreeLine: false, this.isThreeLine: false,
this.isDense: false, this.dense: false,
this.enabled: true,
this.onTap, this.onTap,
this.onLongPress this.onLongPress
}) : super(key: key) { }) : super(key: key) {
...@@ -35,20 +36,26 @@ class ListItem extends StatelessComponent { ...@@ -35,20 +36,26 @@ class ListItem extends StatelessComponent {
final Widget secondary; final Widget secondary;
final Widget right; final Widget right;
final bool isThreeLine; final bool isThreeLine;
final bool isDense; final bool dense;
final bool enabled;
final GestureTapCallback onTap; final GestureTapCallback onTap;
final GestureLongPressCallback onLongPress; final GestureLongPressCallback onLongPress;
TextStyle primaryTextStyle(BuildContext context) { TextStyle primaryTextStyle(BuildContext context) {
final TextStyle style = Theme.of(context).text.subhead; final ThemeData theme = Theme.of(context);
return isDense ? style.copyWith(fontSize: 13.0) : style; final TextStyle style = theme.text.subhead;
if (!enabled) {
final Color color = theme.disabledColor;
return dense ? style.copyWith(fontSize: 13.0, color: color) : style.copyWith(color: color);
}
return dense ? style.copyWith(fontSize: 13.0) : style;
} }
TextStyle secondaryTextStyle(BuildContext context) { TextStyle secondaryTextStyle(BuildContext context) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final Color color = theme.text.caption.color; final Color color = theme.text.caption.color;
final TextStyle style = theme.text.body1; final TextStyle style = theme.text.body1;
return isDense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color); return dense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color);
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -56,15 +63,15 @@ class ListItem extends StatelessComponent { ...@@ -56,15 +63,15 @@ class ListItem extends StatelessComponent {
final bool isOneLine = !isThreeLine && !isTwoLine; final bool isOneLine = !isThreeLine && !isTwoLine;
double itemHeight; double itemHeight;
if (isOneLine) if (isOneLine)
itemHeight = isDense ? 48.0 : 56.0; itemHeight = dense ? 48.0 : 56.0;
else if (isTwoLine) else if (isTwoLine)
itemHeight = isDense ? 60.0 : 72.0; itemHeight = dense ? 60.0 : 72.0;
else else
itemHeight = isDense ? 76.0 : 88.0; itemHeight = dense ? 76.0 : 88.0;
double iconMarginTop = 0.0; double iconMarginTop = 0.0;
if (isThreeLine) if (isThreeLine)
iconMarginTop = isDense ? 8.0 : 16.0; iconMarginTop = dense ? 8.0 : 16.0;
// Overall, the list item is a Row() with these children. // Overall, the list item is a Row() with these children.
final List<Widget> children = <Widget>[]; final List<Widget> children = <Widget>[];
...@@ -113,8 +120,8 @@ class ListItem extends StatelessComponent { ...@@ -113,8 +120,8 @@ class ListItem extends StatelessComponent {
} }
return new InkWell( return new InkWell(
onTap: onTap, onTap: enabled ? onTap : null,
onLongPress: onLongPress, onLongPress: enabled ? onLongPress : null,
child: new Container( child: new Container(
height: itemHeight, height: itemHeight,
padding: const EdgeDims.symmetric(horizontal: 16.0), padding: const EdgeDims.symmetric(horizontal: 16.0),
......
...@@ -6,8 +6,12 @@ import 'dart:async'; ...@@ -6,8 +6,12 @@ import 'dart:async';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'icon.dart';
import 'icon_button.dart'; import 'icon_button.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'ink_well.dart'; import 'ink_well.dart';
import 'list_item.dart';
import 'material.dart'; import 'material.dart';
import 'theme.dart'; import 'theme.dart';
...@@ -26,22 +30,37 @@ class PopupMenuItem<T> extends StatelessComponent { ...@@ -26,22 +30,37 @@ class PopupMenuItem<T> extends StatelessComponent {
PopupMenuItem({ PopupMenuItem({
Key key, Key key,
this.value, this.value,
this.disabled: false, this.enabled: true,
this.hasDivider: false, this.hasDivider: false,
this.child this.child
}) : super(key: key); }) : super(key: key);
final T value; final T value;
final bool disabled; final bool enabled;
final bool hasDivider; final bool hasDivider;
final Widget child; final Widget child;
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
TextStyle style = theme.text.subhead; TextStyle style = theme.text.subhead;
if (disabled) if (!enabled)
style = style.copyWith(color: theme.disabledColor); style = style.copyWith(color: theme.disabledColor);
Widget item = new DefaultTextStyle(
style: style,
child: new Baseline(
baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
child: child
)
);
if (!enabled) {
final bool isDark = theme.brightness == ThemeBrightness.dark;
item = new IconTheme(
data: new IconThemeData(opacity: isDark ? 0.5 : 0.38),
child: item
);
}
return new MergeSemantics( return new MergeSemantics(
child: new Container( child: new Container(
height: _kMenuItemHeight, height: _kMenuItemHeight,
...@@ -49,18 +68,31 @@ class PopupMenuItem<T> extends StatelessComponent { ...@@ -49,18 +68,31 @@ class PopupMenuItem<T> extends StatelessComponent {
decoration: !hasDivider ? null : new BoxDecoration( decoration: !hasDivider ? null : new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor)) border: new Border(bottom: new BorderSide(color: theme.dividerColor))
), ),
child: new DefaultTextStyle( child: item
style: style,
child: new Baseline(
baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
child: child
)
)
) )
); );
} }
} }
class CheckedPopupMenuItem<T> extends PopupMenuItem<T> {
CheckedPopupMenuItem({
Key key,
T value,
checked: false,
bool enabled: true,
Widget child
}) : super(
key: key,
value: value,
enabled: enabled,
child: new ListItem(
enabled: enabled,
left: new Icon(icon: checked ? 'action/done' : null),
primary: child
)
);
}
class _PopupMenu<T> extends StatelessComponent { class _PopupMenu<T> extends StatelessComponent {
_PopupMenu({ _PopupMenu({
Key key, Key key,
...@@ -80,7 +112,7 @@ class _PopupMenu<T> extends StatelessComponent { ...@@ -80,7 +112,7 @@ class _PopupMenu<T> extends StatelessComponent {
parent: route.animation, parent: route.animation,
curve: new Interval(start, end) curve: new Interval(start, end)
); );
final bool disabled = route.items[i].disabled; final bool enabled = route.items[i].enabled;
Widget item = route.items[i]; Widget item = route.items[i];
if (route.initialValue != null && route.initialValue == route.items[i].value) { if (route.initialValue != null && route.initialValue == route.items[i].value) {
item = new Container( item = new Container(
...@@ -91,7 +123,7 @@ class _PopupMenu<T> extends StatelessComponent { ...@@ -91,7 +123,7 @@ class _PopupMenu<T> extends StatelessComponent {
children.add(new FadeTransition( children.add(new FadeTransition(
opacity: opacity, opacity: opacity,
child: new InkWell( child: new InkWell(
onTap: disabled ? null : () { Navigator.pop(context, route.items[i].value); }, onTap: enabled ? () { Navigator.pop(context, route.items[i].value); } : null,
child: item child: item
) )
)); ));
...@@ -298,7 +330,7 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> { ...@@ -298,7 +330,7 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
) )
) )
.then((T value) { .then((T value) {
if (config.onSelected != null) if (value != null && config.onSelected != null)
config.onSelected(value); config.onSelected(value);
}); });
} }
......
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