构建小部件时如何控制null

Posted

技术标签:

【中文标题】构建小部件时如何控制null【英文标题】:How to control null when bulding widget 【发布时间】:2021-04-18 09:33:10 【问题描述】:

您能告诉我如何在下一页包含 Image.file 的条件吗?我只想在 controller.imagenot null 时构建它。

我收到一个错误: 在构建 Container(padding: E​​dgeInsets.all(32.0)) 时引发了以下 NoSuchMethodError: 在 null 上调用了方法“[]”。 接收方:空 尝试调用:

当我第一次重定向到这个页面时(并且 controller.image 为空):

class HomePage extends GetView<HomeController> 


  final myController1 = TextEditingController();
  final myController2 = TextEditingController();


  @override
  Widget build(BuildContext context) 



    return Scaffold(
      appBar: AppBar(
        title: Text('Grobonet'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
            children: <Widget>[
              TextField(
                controller: myController1,
                decoration: InputDecoration(
                    border: InputBorder.none,
                    hintText: 'Nazwisko'),

              ),
              TextField(
                controller: myController2,
                decoration: InputDecoration(
                    border: InputBorder.none,
                    hintText: 'Miejscowosc'),

              ),
              IconButton(
                icon: Icon(
                  Icons.add,
                  size: 30,
                ),
                onPressed: () =>
                    Get.toNamed(
                        AppRoutes.PICK_IMAGE
                    ),
                color: Colors.pink,
              ),
              IconButton(
                icon: Icon(
                  Icons.save_outlined,
                  size: 30,
                ),
                /*onPressed: () =>
                    Get.toNamed(
                        AppRoutes.PICK_IMAGE
                    ),*/
                color: Colors.pink,
              ),


              Container(
                padding: EdgeInsets.all(32),
                child:  GetBuilder<HomeController>(
                  builder: (_) 
                    return Image.file(controller.image);
                  ,
                ),
              ),

            ]
        ),
      ),

    );

  

控制器:

class HomeController extends GetxController 

 final image = Get.arguments['image'];
 final file_loaded = Get.arguments['file_loaded'];



【问题讨论】:

【参考方案1】:

您可以使用collection-if。只需像这样添加if (controller.image != null)

          if (controller?.image != null)
          Container(
            padding: EdgeInsets.all(32),
            child:  GetBuilder<HomeController>(
              builder: (_) 
                return Image.file(controller.image);
              ,
            ),
          ),

【讨论】:

这也可能引发错误。 Null check on a null object。如果控制器为空。 为了安全起见,我添加了条件成员访问权限。谢谢。 这仍然会引发异常:在构建 HomePage(dirty) 时引发了以下 NoSuchMethodError:在 null 上调用了方法“[]”。接收者:null 尝试调用:[]("image") 我添加了控制器代码以供参考【参考方案2】:

在控制器的 onInit() 方法中使用获取您的参数:

class HomeController extends GetxController 

   final File image;
   final File file_loaded;

   onInit()
    image = Get.arguments['image'];
    file_loaded = Get.arguments['file_loaded'];
  


这样,除了Get.arguments 实际为空之外,您不需要执行额外的空检查。

更新 你还需要像这样更新你的视图:

 Container(
        padding: EdgeInsets.all(32),
        child:  GetBuilder<HomeController>(
          builder: (_) 
            return Image.file(_.image); // not return Image.file(controller.image);
                                                // _ here is the instance of HomeController given by the GetBuilder
          ,
        ),
      ),

更新 2 正如您在 cmets 中提到的,您希望将数据从第二个页面 (OCRDetailsPage) 发送到先前打开的页面 (HomePage)。然后你不需要传递参数。您可以使用 Get.find()OCRDetailsPage 中获取 HomeController 实例,然后设置变量并更新状态,如下所示:

class OCRDetailsPage extends StatelessWidget 
    @override
    Widget build(BuildContext context) 
      final OCRDetailsController controller = Get.find();
      return Scaffold(
      appBar: AppBar(title: Text('OCR Details Page')),
      body: Center(
        child: FlatButton(
          color: Colors.blue,
          child: Icon(Icons.save_outlined),
          onPressed: () 
            final HomeController homeController = Get.find();
            homeController.ocr_text = controller.text;
            homeController.update();
            Get.toNamed(
              AppRoutes.HOME,
            );
           
          ),
       ),
     );
   
 

【讨论】:

我确实喜欢听从您的指导,但仍然遇到同样的错误。我不确定你是否理解一个问题,我有 2 个页面:主页和 OCR 详细信息 - 使用主页启动应用程序 - 进入 OCR 详细信息页面(显示 ocr 图像详细信息) - 在按下 OCR 详细信息上的按钮后,我想返回 ocr主页的图像详细信息所以第一次启动应用程序时出现空错误,因为 get.arguments 为空

以上是关于构建小部件时如何控制null的主要内容,如果未能解决你的问题,请参考以下文章

如何构建一个在拉伸时显示更多按钮的 android 小部件?

如何在构建有状态小部件之前等待功能? [复制]

NoSuchMethodError,小部件库捕获的异常

使用 Hive 框数据构建小部件

如何布局 GridView.count 以便小部件从 Flutter 中的父小部件顶部开始构建?

如何使用颤振构建小部件?