文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Flutter中使用Overlay传入context提示:Null check operator used on a null value(对空值使用空检查运算符)

2023-10-04 09:32

关注

首先此时使用的是GetX框架,框架截图如下:

View中代码如下:

class AddTaskPage extends StatelessWidget {  const AddTaskPage({Key? key}) : super(key: key);  @override  Widget build(BuildContext context) {    final logic = Get.put(AddTaskLogic());    final state = Get.find().state;    return Scaffold(      appBar: AppBar(        backgroundColor: Tcolor.barBackgroudColor,        elevation: 0,      ),      body: _addTaskContent(state),    );  }  _addTaskContent(AddTaskState addTaskState) {    return GetBuilder(builder: (logic) {      return Container(        child: Column(          children: [            //任务类型 0-工作 1-学习 2-生活            Container(              key: logic.typeKey,              child: InputFied(                  fieldwidth: 300,                  hintText: "请选择任务类型",                  controller: addTaskState.contentController,                  iconWidget: InkWell(                    child: Icon(addTaskState.typeExpand?Icons.expand_less_outlined:Icons.expand_more,color: Colors.grey,size: 18,),                    onTap: (){                      print("弹出任务类型选择框");                      logic.selectTypePop();                    },                  )              ),            ),          ],        ),      );    });  }}

logic代码

class AddTaskLogic extends GetxController {  final AddTaskState state = AddTaskState();  GlobalKey typeKey = GlobalKey();  //弹出任务类型选择框  selectTypePop(){    state.typeExpand=!state.typeExpand;    update();    RenderBox typeBox = typeKey.currentContext!.findRenderObject() as RenderBox;    print("要开始构建了Pop了");        PopToastManager().buildUI(      context: Get.context!,      isClickDiss: true,      X: typeBox.localToGlobal(Offset.zero).dx + 28 + 76,      Y: typeBox.localToGlobal(Offset.zero).dy + 26,      offx: 0,      offy: 0,      width: 260,      height: 90,      childWidget: ListView.builder(        itemCount: state.taskType.length,        itemBuilder: (context, index) {          print("构建UI");          return Container(            child: Row(              children: [                ClipRRect(                  borderRadius: BorderRadius.circular(60),                  child: Container(                    width: 13,                    height: 13,                    decoration: BoxDecoration(                      color: state.typeColor[index],                    ),                  ),                ),                SizedBox(width: 20,),                Text(state.taskType[index]),              ],            ),          );        },      ),    );    update();  }}

对Overlay的使用封装了一个单独的类PopToastManager(),PopToastManager()代码如下:

import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';//封装一个构造弹窗类class PopToastManager{    OverlayEntry? _overlayEntry;    static PopToastManager? _manager;    PopToastManager._();    factory PopToastManager(){    if(_manager==null){      _manager=PopToastManager._();    }    return _manager!;  }    void buildUI(      {        required BuildContext context,        required bool isClickDiss,        required double X,        required double Y,        required double offx,        required double offy,        required double width,        required double height,        required Widget childWidget,        Function? dismissCallBack      }){    //创建 overlayEntry    OverlayEntry overlayEntry=OverlayEntry(        builder: (context){          print("开始构建overlayEntry");          return GestureDetector(            behavior:HitTestBehavior.opaque ,                        onTap: (){                            if(isClickDiss){                                if (dismissCallBack != null) {                  dismissCallBack();                }                                dissmiss();              }            },                        child: Container(              width: MediaQuery.of(context).size.width,              height: MediaQuery.of(context).size.height,              color: Colors.transparent,              child: Column(                crossAxisAlignment: CrossAxisAlignment.start,                children: [                  // Container(height: Y,),                  SizedBox(height: Y,),                  Container(                    margin: EdgeInsets.fromLTRB(offx + X,offy, 0, 0),                    width: width,                    height: height,                    child: childWidget,                  ),                ],              ),            ),          );        });    this._overlayEntry = overlayEntry;    //插入到 Overlay中显示 OverlayEntry    Overlay.of(context)!.insert(overlayEntry);      }  void dissmiss(){    if(this._overlayEntry != null){      print("蒙层消失");      this._overlayEntry!.remove();      this._overlayEntry = null;    }  }}

运行结果如下:

 根据打印的语句可以得知,代码根本没有开始构建OverlayEntry(builder:(context){})

查看错误,发现问题出现在对Overlay.of(context)!.insert(overlayEntry);中context的空值判断

于是我首先在PopToastManager()类buildUI()方法中添加对context是否为空的判断

 

此时运行结果

说明:此时传入的context不为空但是Overlay.of(context)为空

为什么会这样?

首先:需要知道Overlay.of(context)意味着什么?

据搜索Overlay 是一个可以在应用程序中显示浮动元素的特殊 Widget。Overlay.of(context)是Flutter框架中的一个方法,用于获取指定上下文中最近的Overlay,Overlay.of(context) 方法返回的对象可以用于向 Overlay 中添加浮动元素。

如果 Overlay.of(context) 返回 null,则表示指定上下文中没有找到 Overlay。这通常是由于没有在该上下文的 Widget 树中添加 Overlay 导致的。在使用 Overlay.of(context) 之前,需要确保在应用程序的 Widget 树中添加了 Overlay。

此时可推测:

在上下文中没有添加Overlay,所以不能向Overlay 中添加浮动元素x

上下文出现了问题

 试解决问题(1):

 

 出错的原因:

1、在 Flutter 中,context 是一个非常重要的概念,它代表了 widget 在 widget 树中的位置。context 的不同,可能会影响到你能够访问到的 widget 或者 state。

2、在代码中传入context时使用了 Get.context。Get 是一个用于状态管理和依赖注入的库,它的 context 是全局的,可能并不在你当前 widget 的 widget 树中。因此,当你使用 Get.context 时,你可能得到的是一个全局的、不在当前 widget 树中的 context。


3、但是 Overlay.of(context) 需要一个在当前 widget 树中的 context 才能正常工作。如果你传入的 context 不在当前 widget 树中,Overlay.of(context) 就会返回 null。

4、所以,即使 Get.context 不为 null,Overlay.of(Get.context) 也可能为 null,因为 Get.context 可能不在当前 widget 树中。

要解决这个问题,你需要确保你传入 Overlay.of(context) 的 context 是在当前 widget 树中的。

将context作为参数传入进selectTypePop()

 

来源地址:https://blog.csdn.net/weixin_43244083/article/details/131471321

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯