diff --git a/dev/benchmarks/complex_layout/lib/main.dart b/dev/benchmarks/complex_layout/lib/main.dart index e7e8cec0ca0..6c985b6fe64 100644 --- a/dev/benchmarks/complex_layout/lib/main.dart +++ b/dev/benchmarks/complex_layout/lib/main.dart @@ -101,7 +101,7 @@ class TopBarMenu extends StatelessWidget { Widget build(BuildContext context) { return new PopupMenuButton( onSelected: (String value) { print("Selected: $value"); }, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: "Friends", child: new MenuItemWithIcon(Icons.people, "Friends", "5 new") diff --git a/examples/material_gallery/lib/demo/flexible_space_demo.dart b/examples/material_gallery/lib/demo/flexible_space_demo.dart index 3fcd018e168..496d06100ae 100644 --- a/examples/material_gallery/lib/demo/flexible_space_demo.dart +++ b/examples/material_gallery/lib/demo/flexible_space_demo.dart @@ -110,7 +110,7 @@ class FlexibleSpaceDemoState extends State { _appBarBehavior = value; }); }, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: AppBarBehavior.scroll, child: new Text('AppBar scrolls away') diff --git a/examples/material_gallery/lib/demo/leave_behind_demo.dart b/examples/material_gallery/lib/demo/leave_behind_demo.dart index e5a406ce00f..26708ea6c06 100644 --- a/examples/material_gallery/lib/demo/leave_behind_demo.dart +++ b/examples/material_gallery/lib/demo/leave_behind_demo.dart @@ -134,7 +134,7 @@ class LeaveBehindDemoState extends State { actions: [ new PopupMenuButton( onSelected: handleDemoAction, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: LeaveBehindDemoAction.reset, child: new Text('Reset the list') diff --git a/examples/material_gallery/lib/demo/menu_demo.dart b/examples/material_gallery/lib/demo/menu_demo.dart index c357e36527f..caff060e0f6 100644 --- a/examples/material_gallery/lib/demo/menu_demo.dart +++ b/examples/material_gallery/lib/demo/menu_demo.dart @@ -64,7 +64,7 @@ class MenuDemoState extends State { actions: [ new PopupMenuButton( onSelected: showMenuSelection, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: 'AppBar Menu', child: new Text('AppBar Menu') @@ -91,7 +91,7 @@ class MenuDemoState extends State { title: new Text('An item with a context menu button'), trailing: new PopupMenuButton( onSelected: showMenuSelection, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: _simpleValue1, child: new Text('Context menu item one') @@ -114,7 +114,7 @@ class MenuDemoState extends State { title: new Text('An item with a sectioned menu'), trailing: new PopupMenuButton( onSelected: showMenuSelection, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: 'Preview', child: new ListItem( @@ -157,7 +157,7 @@ class MenuDemoState extends State { title: new Text('An item with a simple menu'), subtitle: new Text(_simpleValue) ), - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: _simpleValue1, child: new Text(_simpleValue1) @@ -178,7 +178,7 @@ class MenuDemoState extends State { title: new Text('An item with a checklist menu'), trailing: new PopupMenuButton( onSelected: showCheckedMenuSelections, - items: >[ + itemBuilder: (BuildContext context) => >[ new CheckedPopupMenuItem( value: _checkedValue1, checked: isChecked(_checkedValue1), diff --git a/examples/material_gallery/lib/demo/scrollable_tabs_demo.dart b/examples/material_gallery/lib/demo/scrollable_tabs_demo.dart index fbcfde70ceb..21cd8aff7c1 100644 --- a/examples/material_gallery/lib/demo/scrollable_tabs_demo.dart +++ b/examples/material_gallery/lib/demo/scrollable_tabs_demo.dart @@ -53,7 +53,7 @@ class ScrollableTabsDemoState extends State { actions: [ new PopupMenuButton( onSelected: changeDemoStyle, - items: >[ + itemBuilder: (BuildContext context) => >[ new PopupMenuItem( value: TabsDemoStyle.iconsAndText, child: new Text('Icons and Text') diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart index e40cb4a4eb2..8992b0535f0 100644 --- a/examples/stocks/lib/stock_home.dart +++ b/examples/stocks/lib/stock_home.dart @@ -220,7 +220,7 @@ class StockHomeState extends State { ), new PopupMenuButton<_StockMenuItem>( onSelected: (_StockMenuItem value) { _handleStockMenu(context, value); }, - items: >[ + itemBuilder: (BuildContext context) => >[ new CheckedPopupMenuItem<_StockMenuItem>( value: _StockMenuItem.autorefresh, checked: _autorefresh, diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index 756082b16c5..c21d4bbee42 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -380,6 +380,9 @@ Future showMenu/**/({ /// its menu to be dismissed. typedef void PopupMenuItemSelected(T value); +/// Signature used by [PopupMenuButton] to lazily construct the items shown when the button is pressed. +typedef List> PopupMenuItemBuilder(BuildContext context); + /// Displays a menu when pressed and calls [onSelected] when the menu is dismissed /// because an item was selected. The value passed to [onSelected] is the value of /// the selected menu item. If child is null then a standard 'navigation/more_vert' @@ -387,15 +390,18 @@ typedef void PopupMenuItemSelected(T value); class PopupMenuButton extends StatefulWidget { PopupMenuButton({ Key key, - this.items, + this.itemBuilder, this.initialValue, this.onSelected, this.tooltip: 'Show menu', this.elevation: 8, this.child - }) : super(key: key); + }) : super(key: key) { + assert(itemBuilder != null); + } - final List> items; + /// Called when the button is pressed to create the items to show in the menu. + final PopupMenuItemBuilder itemBuilder; final T initialValue; @@ -420,7 +426,7 @@ class _PopupMenuButtonState extends State> { showMenu/**/( context: context, elevation: config.elevation, - items: config.items, + items: config.itemBuilder(context), initialValue: config.initialValue, position: new ModalPosition( left: topLeft.x,