Flutter 中由 BuildContext 引发的血案
今天和各位分享一个博主在实际开发中遇到的问题,以及解决方法。废话不多说,我们先来看需求:
我们要做一个iOS风格的底部菜单弹出组件,具体涉及showCupertinoModalPopup()方法,该方法被执行后,会出现如下图类似所示的菜单弹出视图:

相信这个弹出菜单视图都有见过吧?下面重点来了:在本次的项目需求中,该视图的选项文字是由Server端返回的。也就是说,这些选项的内容和个数都不固定,因此不能将其在代码中写固定值。
为了简化代码以突出重点,下面放上我在一开始的实现方案:
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对象是谁呢?它在这里:
showCupertinoModalPopup(
context: context,
builder: (buildContext) {
return CupertinoActionSheet(
title: Text('测试菜单'),
message: Text('点击菜单项试试吧!'),
actions: menuWidgets);
}
);
注意到了吗?上面第三行括号里的buildContext才是我们真正要用的对象。因此,正确的做法是什么呢?
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);
});
}
如上所示,我们只需将正确的对象“带”到其作用域外面就可以了。
好了,这就是本篇文章的全部内容,希望能够对你有所帮助!
Flutter 中由 BuildContext 引发的血案的更多相关文章
- flutter中的BuildContext
https://www.jianshu.com/p/509b77b26b78
- 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
- 一个无锁消息队列引发的血案(五)——RingQueue(中) 休眠的艺术
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
- 一个字母引发的血案 java.io.File中mkdir()和mkdirs()
一个字母引发的血案 明天开始放年假了,临放假前有个爬虫的任务,其中需要把网络图片保存到本地,很简单,马上写完了代码: //省略部分代码... Long fileId= (Long) data.get( ...
- [WCF]缺少一行代码引发的血案
这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性.具体来说,这是一个关于如何自动为服务接口(契约 ...
- dubbox微服务实例及引发的“血案”
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
- Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
- Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
- 由Java中toString()方法引发的无意识的递归想到的
先看一段很简单的java代码: toString()/** * @author jeffwong */ public class InfiniteRecursion { public String t ...
随机推荐
- 模仿 SWPU邮件页面
模仿SWPU邮件页面 要求 参考swpu 邮件主页,编写一个新闻后台登录页面,并用Js静态验证用户名密码是否为空,用户名为tom 密码为 123跳转到另一个页面 http://mail.swpu.ed ...
- [A*算法]基于Unity实现A*算法(二)
写在前面:上一篇当时是非常简单的了解一下A*,昨天还有一些问题没解决,就暂时把自己查阅的文坛摘抄了过来(毕竟人家写的比我要好的多 :> ) 今天终于解决了,就又写了这一篇,正好我自己再梳理一遍, ...
- 委托 事件 observer
详细介绍http://www.cnblogs.com/jcz1206/articles/2730793.html ---摘录别人的 using System;using System.Collect ...
- 【情感分析必备】python文件读写:codecs
codecs在读取文件时,发生错误: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbe in position 0: invalid s ...
- java-五大内存图
jrm—Java虚拟机在进行程序运行时会向cpu申请一个内存约为10%左右,该内存被jrm分为5大区域 一:栈内存(stack)用来存储变量 当栈消失时,变量也随之消失.二:堆内存(heap)在Jav ...
- 引入mybatis-plus报 Invalid bound statement错误怎么办,动动手指改一个地方就行
错误 Mybatis-Plus (简称MP) 是mybatis的一个增强工具,在mybatis的基础上只做增强不做改变,简化了开发效率.其实就是帮我们封装了一些简单的curd方法,可以直接调用,不必再 ...
- nodejs 开发服务端 部署到 iis 服务器环境 -- iisnode 安装问题解决记录
开发环境 nodejs: v10.15.3 windows: 10 iis: 10 需求: 用Nodejs开发了服务端,要部署到IIS 需要在IIS服务器上安装iisnode,结果遇到问题:安装不上 ...
- 2018京东校招Java笔试题
相比阿里巴巴,京东的题都是考研基础题,加上一点java基础知识和linux命令. 1. 单选题(19道题,每题2分): 1)4个并发进程都需要5个同类资源,则至少需要多少个资源,才不会导致死锁? 2) ...
- DM7的聚簇索引和非聚簇索引(cluster属性)
早期的DM7或者DM8在创建带有主键的表时,默认会加上cluster属性:后期版本则全部为默认非cluster属性. 下面为显示的指定cluster属性: 1.创建主键的为聚集索引. create t ...
- 使用RTL进行硬件模型编程的局限性
https://mp.weixin.qq.com/s/Nj_d3hwgNX4kWVtKsqMSWg 硬件模型编程,即Hardware Model Programming.在RTL抽象级别 ...