我使用PopupMenuButton来编辑listView。对于PopupMenuButton(在listView中删除项、添加项、编辑项(尝试进行回调的每个操作。例如,最简单的情况是删除
//_editorChannels - data with which I fill in the list
delete(dynamic val) {
setState(() => _editorChannels.removeWhere((data) => data == val));
}
但是,由于我将回调函数delete
传递给小部件,所以当我创建它时,会在构建过程中调用错误setState((或markNeedsBuild。如果更改并删除setState()
,则不会发生错误,但当通过回调删除项目时,列表当然不会更新。
delete(dynamic val) {
_editorChannels.removeWhere((data) => data == val);
}
我的弹出菜单按钮小部件
class PopMenuWidget2 extends StatelessWidget {
final VoidCallback onDelete;
const PopMenuWidget2({Key key, this.onDelete}) : super(key: key);
@override
Widget build(BuildContext context) => PopupMenuButton<int>(
onSelected: (result) {
//On View
if (result == 0) {}
//On Edit
if (result == 1) { }
//OnDelete Callback run
if (result == 2) {
onDelete();
}
},
itemBuilder: (context) => [
PopupMenuItem(
value: 0,
child: Row(
children: <Widget>[
Icon(
Icons.remove_red_eye_rounded,
color: Colors.black38,
),
Text(' View Option', style: TextStyle(color: Colors.black38)),
],
),
),
PopupMenuItem(
value: 1,
child: Row(
children: <Widget>[
Icon(
Icons.create,
color: Colors.black38,
),
Text(' Edit Option', style: TextStyle(color: Colors.black38)),
],
),
),
PopupMenuItem(
value: 2,
child: Row(
children: <Widget>[
Icon(
Icons.delete,
color: Colors.black38,
),
Text(' Delete Option',
style: TextStyle(color: Colors.black38)),
],
),
),
],
);
}
主要小工具
class EditorPage extends StatefulWidget {
EditorPage({Key key, this.Channels}) : super(key: key);
final List<Channel> Channels;
static const String routeName = "/EditorPage";
@override
_EditorPageState createState() => new _EditorPageState();
}
class _EditorPageState extends State<EditorPage> {
Stream<Mock> _result;
final _coreObj = new Core();
List<Channel> _editorChannels;
//callback onDelete
delete(dynamic val) {
setState(() => _editorChannels.removeWhere((data) => data == val));
}
@override
void initState() {
_editorChannels = widget.Channels;
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: new Scaffold(
appBar: AppBar(
title: Text(''),
bottom: TabBar(tabs: [
Tab(icon: FaIcon(FontAwesomeIcons.calendarCheck), text: "One"),
Tab(icon: FaIcon(FontAwesomeIcons.tasks), text: "Two"),
]),
),
body: SafeArea(
child: TabBarView(children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Scaffold(
body: ListView.builder(
itemCount: _editorChannels == null
? 0
: _editorChannels.length,
itemBuilder: (context, index) {
final item = _editorChannels[index];
return Card(
shadowColor: Colors.black26,
margin: EdgeInsets.all(3.0),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(2),
),
child: ListTile(
title: Container(
child: Text(
item.Name != null ? item.Name : '',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0),
)),
subtitle: Text(item.Url),
onTap: () => {},
isThreeLine: false,
leading: getIconbyId(item.Status),
//Pass callback
trailing: PopMenuWidget2(
onDelete: delete(item),
)),
);
}),
),
)
],
),
]))));
}
}
要使setState()
工作,需要将PopMenuWidget2
作为StatefulWidget
。更改
class PopMenuWidget2 extends StatelessWidget {
至
class PopMenuWidget2 extends StatefulWidget {
此外将回调函数像链接一样传递给您,而不像函数执行的结果onDelete: () => onDelete(item)
trailing: PopMenuWidget(
onDelete: () => onDelete(item),
)),
完整代码:
class PopMenuWidget2 extends StatefulWidget {
final VoidCallback onDelete;
const PopMenuWidget2({Key key, this.onDelete}) : super(key: key);
@override
_PopMenuWidget2State createState() => _PopMenuWidget2State();
}
class _PopMenuWidget2State extends State<PopMenuWidget2> {
@override
Widget build(BuildContext context) => PopupMenuButton<int>(
onSelected: (result) {
//On View
if (result == 0) {}
//On Edit
if (result == 1) { }
//OnDelete Callback run
if (result == 2) {
onDelete();
}
},
itemBuilder: (context) => [
PopupMenuItem(
value: 0,
child: Row(
children: <Widget>[
Icon(
Icons.remove_red_eye_rounded,
color: Colors.black38,
),
Text(' View Option', style: TextStyle(color: Colors.black38)),
],
),
),
PopupMenuItem(
value: 1,
child: Row(
children: <Widget>[
Icon(
Icons.create,
color: Colors.black38,
),
Text(' Edit Option', style: TextStyle(color: Colors.black38)),
],
),
),
PopupMenuItem(
value: 2,
child: Row(
children: <Widget>[
Icon(
Icons.delete,
color: Colors.black38,
),
Text(' Delete Option',
style: TextStyle(color: Colors.black38)),
],
),
),
],
);
}
您必须定义自定义类型:,而不是使用VoidCallback
typedef MyCustomCallback<T> = void Function(T value);
并将onDelete定义更改为:
final MyCustomCallback onDelete;
最后将回调调用修复为:
if (result == 2) {
onDelete(value);
}
// ...
trailing: PopMenuWidget2(
onDelete: (item) => delete(item),
)),