Nuo*_*oYi 6 popupmenubutton flutter
我试图让菜单保持打开状态,以便我可以一次选择多个类别,而无需在每次选择后快速返回页面。
如果它可以像 Excel 过滤数据(或 Libreoffice Autofilter)那样运行就完美了
添加了截图
任何想法,将不胜感激!
代码:
import 'package:flutter/material.dart';
void main() { return runApp(MaterialApp(
home: MenuDemo(), )); }
class MenuDemo extends StatefulWidget { const MenuDemo({Key key}) : super(key: key);
static const String routeName = '/material/menu';
@override MenuDemoState createState() => new MenuDemoState(); }
class MenuDemoState extends State<MenuDemo> { final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final String _checkedValue1 = 'One'; final String _checkedValue2 = 'Two'; final String _checkedValue3 = 'Free'; final String
_checkedValue4 = 'Four'; List<String> _checkedValues;
@override void initState() {
super.initState();
_checkedValues = <String>[_checkedValue3]; }
void showInSnackBar(String value) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(value))); }
void showCheckedMenuSelections(String value) {
if (_checkedValues.contains(value))
_checkedValues.remove(value);
else
_checkedValues.add(value);
showInSnackBar('Checked $_checkedValues'); }
bool isChecked(String value) => _checkedValues.contains(value);
@override Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
body: Center(
child: Container(
width: 250.0,
child: new ListTile(
title: const Text(
'checklist menu',
textAlign: TextAlign.center,
),
trailing: new PopupMenuButton<String>(
padding: EdgeInsets.zero,
onSelected: showCheckedMenuSelections,
itemBuilder: (BuildContext context) =>
<PopupMenuItem<String>>[
new CheckedPopupMenuItem<String>(
value: _checkedValue1,
checked: isChecked(_checkedValue1),
child: new Text(_checkedValue1)),
new CheckedPopupMenuItem<String>(
value: _checkedValue2,
//enabled: false,
checked: isChecked(_checkedValue2),
child: new Text(_checkedValue2)),
new CheckedPopupMenuItem<String>(
value: _checkedValue3,
checked: isChecked(_checkedValue3),
child: new Text(_checkedValue3)),
new CheckedPopupMenuItem<String>(
value: _checkedValue4,
checked: isChecked(_checkedValue4),
child: new Text(_checkedValue4))
])),
),
)); } }
Run Code Online (Sandbox Code Playgroud)
Oma*_*att -1
您可以创建自己的多选弹出菜单,因为使用默认的 PopupMenu 会在选择项目时关闭对话框。
class MultiSelectDialogItem<V> {
const MultiSelectDialogItem(this.value, this.label);
final V value;
final String label;
}
class MultiSelectDialog<V> extends StatefulWidget {
const MultiSelectDialog(
{Key? key, required this.items, this.initialSelectedValues})
: super(key: key);
final List<MultiSelectDialogItem<V>> items;
final Set<V>? initialSelectedValues;
@override
State<StatefulWidget> createState() => _MultiSelectDialogState<V>();
}
class _MultiSelectDialogState<V> extends State<MultiSelectDialog<V>> {
final _selectedValues = <V>{};
@override
void initState() {
super.initState();
if (widget.initialSelectedValues != null) {
_selectedValues.addAll(widget.initialSelectedValues!);
}
}
void _onItemCheckedChange(V itemValue, bool checked) {
setState(() {
if (checked) {
_selectedValues.add(itemValue);
} else {
_selectedValues.remove(itemValue);
}
});
}
void _onCancelTap() {
Navigator.pop(context);
}
void _onSubmitTap() {
Navigator.pop(context, _selectedValues);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Select items'),
contentPadding: const EdgeInsets.only(top: 12.0),
content: SingleChildScrollView(
child: ListTileTheme(
contentPadding: const EdgeInsets.fromLTRB(14.0, 0.0, 24.0, 0.0),
child: ListBody(
children: widget.items.map(_buildItem).toList(),
),
),
),
actions: <Widget>[
ElevatedButton(
child: const Text('Cancel'),
onPressed: _onCancelTap,
),
ElevatedButton(
child: const Text('Ok'),
onPressed: _onSubmitTap,
)
],
);
}
Widget _buildItem(MultiSelectDialogItem<V> item) {
final checked = _selectedValues.contains(item.value);
return CheckboxListTile(
value: checked,
title: Text(item.label),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (checked) =>
_onItemCheckedChange(item.value, checked ?? false),
);
}
}
Run Code Online (Sandbox Code Playgroud)
然后显示菜单。
void _showMultiSelect(BuildContext context) async {
// set value and label on MultiSelectDialogItem
final items = <MultiSelectDialogItem<int>>[
const MultiSelectDialogItem(1, 'Item 1'),
const MultiSelectDialogItem(2, 'Item 2'),
const MultiSelectDialogItem(3, 'Item 3'),
];
final selectedValues = await showDialog<Set<int>>(
context: context,
builder: (BuildContext context) {
return MultiSelectDialog(
items: items,
// use Set to configure initial selected value
// i.e. initialSelectedValues: const {1,2}
initialSelectedValues: null,
);
},
);
// Fetch selected items
debugPrint('Selected Values: $selectedValues');
}
Run Code Online (Sandbox Code Playgroud)
完整样品
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _showMultiSelect(BuildContext context) async {
final items = <MultiSelectDialogItem<int>>[
const MultiSelectDialogItem(1, 'Item 1'),
const MultiSelectDialogItem(2, 'Item 2'),
const MultiSelectDialogItem(3, 'Item 3'),
];
final selectedValues = await showDialog<Set<int>>(
context: context,
builder: (BuildContext context) {
return MultiSelectDialog(
items: items,
initialSelectedValues: null,
);
},
);
debugPrint('Selected Values: $selectedValues');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ElevatedButton(
onPressed: () {
_showMultiSelect(context);
},
child: const Text('Show Dropdown Multiselect'),
),
),
);
}
}
class MultiSelectDialogItem<V> {
const MultiSelectDialogItem(this.value, this.label);
final V value;
final String label;
}
class MultiSelectDialog<V> extends StatefulWidget {
const MultiSelectDialog(
{Key? key, required this.items, this.initialSelectedValues})
: super(key: key);
final List<MultiSelectDialogItem<V>> items;
final Set<V>? initialSelectedValues;
@override
State<StatefulWidget> createState() => _MultiSelectDialogState<V>();
}
class _MultiSelectDialogState<V> extends State<MultiSelectDialog<V>> {
final _selectedValues = <V>{};
@override
void initState() {
super.initState();
if (widget.initialSelectedValues != null) {
_selectedValues.addAll(widget.initialSelectedValues!);
}
}
void _onItemCheckedChange(V itemValue, bool checked) {
setState(() {
if (checked) {
_selectedValues.add(itemValue);
} else {
_selectedValues.remove(itemValue);
}
});
}
void _onCancelTap() {
Navigator.pop(context);
}
void _onSubmitTap() {
Navigator.pop(context, _selectedValues);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Select items'),
contentPadding: const EdgeInsets.only(top: 12.0),
content: SingleChildScrollView(
child: ListTileTheme(
contentPadding: const EdgeInsets.fromLTRB(14.0, 0.0, 24.0, 0.0),
child: ListBody(
children: widget.items.map(_buildItem).toList(),
),
),
),
actions: <Widget>[
ElevatedButton(
child: const Text('Cancel'),
onPressed: _onCancelTap,
),
ElevatedButton(
child: const Text('Ok'),
onPressed: _onSubmitTap,
)
],
);
}
Widget _buildItem(MultiSelectDialogItem<V> item) {
final checked = _selectedValues.contains(item.value);
return CheckboxListTile(
value: checked,
title: Text(item.label),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (checked) =>
_onItemCheckedChange(item.value, checked ?? false),
);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1178 次 |
最近记录: |