今天和各位分享一个博主在实际开发中遇到的问题,以及解决方法。废话很少说,咱们先来看需求:
咱们要作一个iOS风格的底部菜单弹出组件,具体涉及showCupertinoModalPopup()方法,该方法被执行后,会出现以下图相似所示的菜单弹出视图:
bash
openActionSheet() {
List<Widget> menuWidgets = new List();
menuItems.forEach((element) {
menuWidgets.add(CupertinoActionSheetAction(
child: Text(element),
onPressed: () {
Navigator.pop(context);
debugPrint("操做$element被执行“); }, isDefaultAction: true, )); }); showCupertinoModalPopup( context: context, builder: (buildContext) { return CupertinoActionSheet( title: Text('测试菜单'), message: Text('点击菜单项试试吧!'), actions: menuWidgets); }); } 复制代码
如上述代码所示,openActionSheet()是显示该组件的方法。其中,showCupertinoModalPopup()为Flutter SDK内置方法,其做用即显示这个组件;再其上面的循环以及List声明、赋值等操做实际上就是在动态添加菜单项。menuItems类型是List<String>。
经过对代码的解释,相信你们可以一目了然地看出,当某个菜单项被点击时,整个菜单组件消失,并打印Debug Log(对应为真实项目要执行的操做)。
你们以为上述代码有问题吗?若是有问题,问题在哪儿呢?
如今公布答案:这段代码有问题!
上述代码执行时,当用户点击菜单项后,其运行结果并不是如咱们预想的那样:菜单组消失并输出Log,而变成了:整个页面被Pop,菜单组保留,并输出Log!
这是什么缘由呢?
实际上,罪魁祸首就在咱们循环遍历赋值操做时的这条语句:测试
Navigator.pop(context);
复制代码
这里的context是整个页面的BuildContext,而非菜单组的。这里咱们要明确一个概念——咱们想Pop谁,必定要用谁的BuildContext对象。
在这里,正确的BuildContext对象是谁呢?它在这里:ui
showCupertinoModalPopup(
context: context,
builder: (buildContext) {
return CupertinoActionSheet(
title: Text('测试菜单'),
message: Text('点击菜单项试试吧!'),
actions: menuWidgets);
}
);
复制代码
注意到了吗?上面第三行括号里的buildContext才是咱们真正要用的对象。所以,正确的作法是什么呢?spa
openActionSheet() {
BuildContext tempContext;
List<Widget> menuWidgets = new List();
menuItems.forEach((element) {
menuWidgets.add(CupertinoActionSheetAction(
child: Text(element),
onPressed: () {
Navigator.pop(tempContext);
debugPrint("操做$element被执行");
},
isDefaultAction: true,
));
});
showCupertinoModalPopup(
context: context,
builder: (buildContext) {
tempContext = buildContext;
return CupertinoActionSheet(
title: Text('测试菜单'),
message: Text('点击菜单项试试吧!'),
actions: menuWidgets);
});
}
复制代码
如上所示,咱们只需将正确的对象“带”到其做用域外面就能够了。
好了,这就是本篇文章的所有内容,但愿可以对你有所帮助!debug