扑动。类型“Null”不是类型转换中类型“String”的子类型

Flutter. type 'Null' is not a subtype of type 'String' in type cast

提问人:Rafay Mushtaq 提问时间:12/8/2022 更新时间:12/9/2022 访问量:711

问:

════════ 小部件库捕获的异常 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ 在构建 Builder 时抛出了以下_CastError: 类型“Null”不是类型转换中类型“String”的子类型

相关的导致错误的小部件是 MaterialApp在此处输入图片描述

我的代码已附上。这是关于麦克斯韦·乌迪米课程的。购买APP模块。当我在edit_product_screen中按下添加按钮时出现错误。他在 2019 年录制了这门课程。我面临此错误。我无法找出错误。任何人,请解决错误。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/product.dart';
import '../providers/products.dart';

class EditProductScreen extends StatefulWidget {
  static const routeName = '/edit-product';
  const EditProductScreen({super.key});

  @override
  State<EditProductScreen> createState() => _EditProductScreenState();
}

class _EditProductScreenState extends State<EditProductScreen> {
  final priceFocus = FocusNode();
  final imageControl = TextEditingController();
  final form = GlobalKey<FormState>();
  var isInit = true;
  var initValues = {
    'title': '',
    'description': '',
    'price': '',
    'imageUrl': ''
  };
  var editProduct =
      Product(id: '', title: '', desc: '', imageUrl: '', price: 0.0);

  @override
  void dispose() {
    priceFocus.dispose();
    imageControl.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    if (isInit) {
      final productid = ModalRoute.of(context)!.settings.arguments as String;
      if (productid != null) {
        editProduct =
            Provider.of<Products>(context, listen: false).findById(productid);
        initValues = {
          'title': editProduct.title,
          'description': editProduct.desc,
          'price': editProduct.price.toString(),
          'imageUrl': '',
        };
        imageControl.text = editProduct.imageUrl;
      }
    }
    isInit = false;
    super.didChangeDependencies();
  }

  void formSave() {
    final valid = form.currentState!.validate();
    if (!valid) {
      return;
    }
    form.currentState!.save();
    if (editProduct.id != null) {
      Provider.of<Products>(context, listen: false)
          .updateProduct(editProduct.id, editProduct);
    } else {
      Provider.of<Products>(context, listen: false).addProduct(editProduct);
    }
    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Edit Product'),
        actions: [
          IconButton(onPressed: formSave, icon: const Icon(Icons.save))
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
            key: form,
            child: ListView(
              children: [
                TextFormField(
                  initialValue: initValues['title'],
                  decoration: const InputDecoration(labelText: 'Title'),
                  textInputAction: TextInputAction.next,
                  onFieldSubmitted: (_) {
                    FocusScope.of(context).requestFocus(priceFocus);
                  },
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: newValue as String,
                      desc: editProduct.desc,
                      imageUrl: editProduct.imageUrl,
                      price: editProduct.price,
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                  validator: (value) {
                    if (value!.isEmpty) {
                      return 'Enter Title';
                    }
                    return null;
                  },
                ),
                TextFormField(
                  initialValue: initValues['price'],
                  decoration: const InputDecoration(labelText: 'Price'),
                  textInputAction: TextInputAction.next,
                  keyboardType: TextInputType.number,
                  focusNode: priceFocus,
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: editProduct.title,
                      desc: editProduct.desc,
                      imageUrl: editProduct.imageUrl,
                      price: double.parse(newValue as String),
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                ),
                TextFormField(
                  initialValue: initValues['description'],
                  decoration: const InputDecoration(labelText: 'Description'),
                  textInputAction: TextInputAction.next,
                  maxLines: 3,
                  keyboardType: TextInputType.multiline,
                  onSaved: (newValue) {
                    editProduct = Product(
                      id: editProduct.id,
                      title: editProduct.title,
                      desc: newValue as String,
                      imageUrl: editProduct.imageUrl,
                      price: editProduct.price,
                      isFavorite: editProduct.isFavorite,
                    );
                  },
                ),
                Row(
                  children: [
                    Container(
                      height: 100,
                      width: 100,
                      margin: const EdgeInsets.only(top: 8, right: 10),
                      decoration: BoxDecoration(
                          border: Border.all(width: 1, color: Colors.grey)),
                      child: imageControl.text.isEmpty
                          ? const Center(child: Text('Enter Url'))
                          : FittedBox(
                              child: Image.network(
                                imageControl.text,
                                fit: BoxFit.cover,
                              ),
                            ),
                    ),
                    Expanded(
                      child: TextFormField(
                        decoration:
                            const InputDecoration(labelText: 'Image Url'),
                        textInputAction: TextInputAction.done,
                        keyboardType: TextInputType.url,
                        controller: imageControl,
                        onFieldSubmitted: (_) {
                          formSave();
                        },
                        onSaved: (newValue) {
                          editProduct = Product(
                            id: editProduct.id,
                            title: editProduct.title,
                            desc: editProduct.desc,
                            imageUrl: newValue as String,
                            price: editProduct.price,
                            isFavorite: editProduct.isFavorite,
                          );
                        },
                      ),
                    ),
                  ],
                ),
              ],
            )),
      ),
    );
  }
}

string flutter null 子类型

评论


答:

0赞 IonicFireBaseApp 12/8/2022 #1

尝试检查这不应该为 nullModalRoute.of(context)!.settings.arguments

0赞 Guilherme Edington 12/8/2022 #2

在 didChangeDependencies 方法中,您正在实例化一个名为 productId 的变量,并从 ModalRoute.of(context).! 中获取一个值。settings.arguments 并转换为 String,但此值可以为 null,这就是为什么您在该行之后检查它是否为 null 的原因。

@override
  void didChangeDependencies() {
    if (isInit) {
      final productid = ModalRoute.of(context)!.settings.arguments as String;
      if (productid != null) {
        editProduct =
            Provider.of<Products>(context, listen: false).findById(productid);
        initValues = {
          'title': editProduct.title,
          'description': editProduct.desc,
          'price': editProduct.price.toString(),
          'imageUrl': '',
        };
        imageControl.text = editProduct.imageUrl;
      }
    }
    isInit = false;
    super.didChangeDependencies();
  }

所以你可以只转换为一个可为空的字符串,我认为你的问题已经解决了

final productid = ModalRoute.of(context)!.settings.arguments as String?;