【问题标题】:null check operator used on null value -用于空值的空检查运算符 -
【发布时间】:2022-07-06 19:43:36
【问题描述】:

我试图实现一项功能,允许用户从图库中选择和显示图片并使用他们的相机,但每次我尝试导航到执行此操作的屏幕时,我都会不断收到“Null check operator用于空值”

这是屏幕上出现此错误的代码-

    class _AddFoodItemState extends State<AddFoodItem> {
  final TextEditingController _descriptionController = TextEditingController();
  final TextEditingController _priceController = TextEditingController();
  final TextEditingController _ingredientsController = TextEditingController();

  Uint8List? _file;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 1.0,
        iconTheme: const IconThemeData(
          color: Colors.black,
        ),
        title: const Text(
          "Inventory",
          style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
        ),
        backgroundColor: Colors.white,
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: const EdgeInsets.symmetric(vertical: 60.0, horizontal: 16.0),
          child: Column(
            children: <Widget>[
              GestureDetector(
                onTap: () => _selectImage(context),
                child: Container(
                  margin: const EdgeInsets.only(),
                  width: MediaQuery.of(context).size.width,
                  height: 210.0,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: MemoryImage(_file!),
                    ),
                  ),
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              Container(
                padding: const EdgeInsets.only(top: 10),
                width: MediaQuery.of(context).size.width,
                margin: const EdgeInsets.symmetric(horizontal: 20),
                child: TextFieldInput(
                  controller: _descriptionController,
                  labelText: 'Meal Name',
                ),
              ),
              Container(
                padding: const EdgeInsets.only(top: 10),
                width: MediaQuery.of(context).size.width,
                margin: const EdgeInsets.symmetric(horizontal: 20),
                child: TextFieldInput(
                  controller: _priceController,
                  labelText: 'price',
                ),
              ),
              Container(
                padding: const EdgeInsets.only(top: 10),
                width: MediaQuery.of(context).size.width,
                margin: const EdgeInsets.symmetric(horizontal: 20),
                child: TextFieldInput(
                  controller: _ingredientsController,
                  labelText: 'Meal description',
                ),
              ),
              const SizedBox(height: 28.0),
              Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  mealSize(context),
                  const SizedBox(height: 9.0),
                  mealSize(context),
                  const SizedBox(height: 9.0),
                  mealSize(context),
                ],
              ),
              const SizedBox(height: 40.0),
              GestureDetector(
                  onTap: () {}, child: const Button(btnText: "Add Food Item")),
            ],
          ),
        ),
      ),
    );
  }

显示对话框的功能,以便我可以选择图像或拍照:

_selectImage(BuildContext context) async {
    return showDialog(
      context: context,
      builder: (context) => SimpleDialog(
        children: [
          SimpleDialogOption(
            onPressed: () async {
              Navigator.of(context).pop();
              Uint8List file = await pickImage(ImageSource.gallery);
              setState(() {
                _file = file;
              });
            },
            child: Row(
              children: const [
                Icon(Icons.folder),
                Text(
                  "Gallery",
                )
              ],
            ),
          ),

打开对话框的函数代码,该对话框为我提供了从图库中选择其他选项或拍照的选项

SimpleDialogOption(
            onPressed: () async {
              Navigator.of(context).pop();
              Uint8List file = await pickImage(ImageSource.camera);
              setState(() {
                _file = file;
              });
            },
            child: Row(
              children: const [
                Icon(Icons.image),
                Text(
                  "Camera",
                )
              ],
            ),
          ),
          SimpleDialogOption(
            onPressed: () {
              Navigator.of(context).pop();
            },
            child: Row(
              children: const [
                Icon(Icons.cancel),
                Text(
                  "Cancel",
                )
              ],
            ),
          ),
        ],
      ),
    );
  }
}

我的pickImage函数代码:

pickImage(ImageSource source) async {
  final ImagePicker imagePicker = ImagePicker();

  XFile? file = await imagePicker.pickImage(source: source);

  if (file != null) {
    return await file.readAsBytes();
  }
  print('no image selected');
}

showSnackBar(String content, BuildContext context) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: Text(content),
    ),
  );
}

【问题讨论】:

  • 错误可能来自image: MemoryImage(_file!),,其中_file 最终是null,因为您没有针对这种情况进行任何检查。
  • id 认为我检查了“if (file != null)”还是我做错了?
  • Uint8List? _file;里面_AddFoodItemState有问题。这个变量的默认值是null
  • 好的,我能做些什么来从根本上解决这个问题?
  • 确保您的代码可以处理_filenull 的情况。您现在使用的! 运算符只是告诉 Dart 它应该忽略任何潜在的null 值并假设变量总是具有null 以外的值的一种方式。然后 Dart 将添加一个运行时检查,这是你得到的,因为你最终“撒谎”给 Dart 关于这个变量永远不会是null。 :)

标签: flutter dart


【解决方案1】:

您将收到 null 错误,因为您在小部件中使用 _file 而不检查其是否为 null。

在您使用 imagePicker 选择图像之前,_file 将包含 null,它将用于在小部件中显示,从而导致您显示的错误。

所以,你可以使用

                DecorationImage(
                  image: _file==null? <Any Placeholder ImageProvider> :MemoryImage(_file!),
                ),

并且不要忘记在 _file 中的数据更改时调用 setState。即,当图像被更改时 采摘

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 2021-12-03
    • 2022-01-18
    • 2021-07-09
    • 2021-04-29
    • 1970-01-01
    • 2021-11-03
    • 2021-02-25
    • 2022-01-06
    相关资源
    最近更新 更多