Merge pull request #2216 from HansMuller/stocks_demo
Add CheckedPopupMenuitem, update the Stocks demo
This commit is contained in:
commit
8edeecbcd0
@ -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> {
|
|||||||
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> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
}
|
}
|
||||||
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> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
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> {
|
|||||||
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> {
|
|||||||
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:
|
|||||||
- 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';
|
|||||||
|
|
||||||
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> {
|
|||||||
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> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
|||||||
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>(
|
||||||
|
@ -1,110 +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 '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';
|
|||||||
/// 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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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';
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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>> {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then((T value) {
|
.then((T value) {
|
||||||
if (config.onSelected != null)
|
if (value != null && config.onSelected != null)
|
||||||
config.onSelected(value);
|
config.onSelected(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user