今天和各位分享一个博主在实际开发中遇到的问题,以及解决方法。废话不多说,我们先来看需求:

我们要做一个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 引发的血案的更多相关文章

  1. flutter中的BuildContext

    https://www.jianshu.com/p/509b77b26b78

  2. 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  3. 一个无锁消息队列引发的血案(五)——RingQueue(中) 休眠的艺术

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  4. 一个字母引发的血案 java.io.File中mkdir()和mkdirs()

    一个字母引发的血案 明天开始放年假了,临放假前有个爬虫的任务,其中需要把网络图片保存到本地,很简单,马上写完了代码: //省略部分代码... Long fileId= (Long) data.get( ...

  5. [WCF]缺少一行代码引发的血案

    这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性.具体来说,这是一个关于如何自动为服务接口(契约 ...

  6. dubbox微服务实例及引发的“血案”

    Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...

  7. Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  8. Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  9. 由Java中toString()方法引发的无意识的递归想到的

    先看一段很简单的java代码: toString()/** * @author jeffwong */ public class InfiniteRecursion { public String t ...

随机推荐

  1. [转载] Objectiv-C 入门一二三

    http://my.oschina.net/fuckphp/blog/92993 http://my.oschina.net/fuckphp/blog/93217 http://my.oschina. ...

  2. 【Redis】List常见应用场景

    常用数据结构 Stack(栈) = LPUSH + LPOP ->FILO Queue(队列) = LPUSH + RPOP Blocking MQ(阻塞队列) = LPUSH + BRPOP ...

  3. SQL——CREATE、ALTER、DROP和VIEW

    CREATE DATABASE - 创建新数据库    语法:CREATE DATABASE database_nameALTER DATABASE - 修改数据库    CREATE TABLE - ...

  4. Oracle 操作权限

    alter user scott account unlock; 解锁 -- 新建用户create user yym identified by 123456; -- 放开用户权限grant conn ...

  5. Unity自定义Log

    有如下两种方式,第一种借助了Unity自身的LogType枚举型:第二种则是纯粹地自己定义: public class Log { public Log(string message, UnityEn ...

  6. 重磅!阿里P8费心整理Netty实战+指南+项目白皮书PDF,总计1.08G

    前言 Netty是一款用于快速开发高性能的网络应用程序的Java框架.它封装了网络编程的复杂性,使网络编程和Web技术的最新进展能够被比以往更广泛的开发人员接触到. Netty不只是一个接口和类的集合 ...

  7. RabbitMQ--其他几种模式

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文RabbitMQ版本为rabbitmq-server-3.7.17,erlang为erlang-22.0.7.请各位去官网查看版本匹配和下载 ...

  8. 06 . Nginx静态资源缓存

    Nginx静态资源 Nginx可以处理静态资源 非Web服务器可以运行处理而生成的文件,即服务器只需要从硬盘或者缓存中读取然后直接给客户端响应即可. 常见的静态资源 # 浏览器渲染: html文件,样 ...

  9. java 单列集合总结

    Collection 接口 add() remove() contains() clear(); size(); 迭代器遍历(普通迭代器,不能再遍历过程中修改集合的长度) List接口 单列集合 有序 ...

  10. Java 蓝桥杯 算法训练 貌似化学

    ** 貌似化学 ** 问题描述 现在有a,b,c三种原料,如果他们按x:y:z混合,就能产生一种神奇的物品d. 当然不一定只产生一份d,但a,b,c的最简比一定是x:y:z 现在给你3种可供选择的物品 ...