dart 类型“Null”不是类型“File”问题的子类型

icomxhvb  于 2023-02-27  发布在  其他
关注(0)|答案(1)|浏览(183)

我做了一个表单,在ListView.builder()中添加图像及其信息,这是图像截图和代码:

class _AddNewProductState extends State<AddNewProduct> {
  String? dropdownValue = 'Fruits';
  String? productName;
  int? productPrice;

  Future<void> openMobileImagePicker() async {
    final XFile? pickedMobileImage =
        await ImagePicker().pickImage(source: ImageSource.gallery);
    if (pickedMobileImage != null) {
      setState(() {
        ImageFiles.mobileImage = File(pickedMobileImage.path);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(15),
          child: SingleChildScrollView(
            child: Center(
              child: Column(
                children: [
                  const Text(
                    'Add New Product To The Market',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 25,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(15),
                    child: Container(
                      width: double.infinity,
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(30),
                        boxShadow: const [
                          BoxShadow(
                            offset: Offset(0, 10),
                            blurRadius: 30,
                          )
                        ],
                      ),
                      child: Padding(
                        padding: const EdgeInsets.all(25),
                        child: Form(
                          key: UniversalKey.formKey,
                          child: Column(
                            children: [
                              ElevatedButton(
                                onPressed: () {
                                  setState(() {
                                    openMobileImagePicker();
                                  });
                                },
                                child: const Text('Add Product Image'),
                              ),
                              const SizedBox(
                                height: 20,
                              ),
                              Container(
                                height: 120,
                                width: 120,
                                decoration: const BoxDecoration(
                                  boxShadow: [
                                    BoxShadow(
                                      blurRadius: 15,
                                      color: Colors.grey,
                                    )
                                  ],
                                  shape: BoxShape.circle,
                                ),
                                child: CircleAvatar(
                                    backgroundImage: (ImageFiles.mobileImage !=
                                            null)
                                        ? Image.file(ImageFiles.mobileImage!,
                                                fit: BoxFit.fill)
                                            .image
                                        : null),
                              ),
                              const SizedBox(
                                height: 20,
                              ),
                              TextFormField(
                                onSaved: (value) {
                                  setState(() {
                                    ProductDetails.productName = value!;
                                  });
                                },
                                decoration: const InputDecoration(
                                    labelText: 'Product Name',
                                    hintText: 'Add Product Name'),
                              ),
                              const SizedBox(
                                height: 20,
                              ),
                              TextFormField(
                                onSaved: (value) {
                                  setState(() {
                                    ProductDetails.productPrice = value!;
                                  });
                                },
                                decoration: const InputDecoration(
                                    labelText: 'Product Price',
                                    hintText: 'Add Product Price'),
                              ),
                              const SizedBox(
                                height: 20,
                              ),
                              DropdownButton<String>(
                                value: dropdownValue,
                                items: productCategory,
                                                               onChanged: (item) =>
                                    setState(() => dropdownValue = item),
                              ),
                              const SizedBox(
                                height: 20,
                              ),
                              ElevatedButton(

                                  onPressed: () {
                                    listOfProducts.add(
                                        {
                                          'productImage' : ProductDetails.productImage,
                                          'productName' : ProductDetails.productName,
                                          'productPrice' : ProductDetails.productPrice,
                                          'productCategory' : dropdownValue,
                                        }
                                    );

                                  }

                                  ,

                                   child: const Text('Add Product!'))
                              ,
                              const SizedBox(
                                height: 20,
                              ),

                              ElevatedButton(onPressed: () {

                                setState(() {
                                  Navigator.push(context, MaterialPageRoute(builder: (context) => const GroceryPage(),),);
                                });
                              }, child: const Text('Go To Hompage'),),

                            ],
                          ),
                        ),
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

当我点击'提交'它应该添加信息在一个ListView.builder(),这是图像截图和代码:

class ProductsListView extends StatelessWidget {

  const ProductsListView({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      scrollDirection: Axis.horizontal,
      itemCount: fruitsList.length,
      itemBuilder: (BuildContext context, int index) {
        return ClipRect(
          child: Container(
            width: 140.0,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(15.0),
              color: Colors.white,
              boxShadow: const [
                BoxShadow(
                  blurRadius: 10,
                  color: Colors.black,
                ),
              ],
            ),
            margin: const EdgeInsets.all(10.0),
            child: Padding(
              padding: const EdgeInsets.fromLTRB(20, 10, 10, 10),
              child: Column(
                children: [
                  Image.file(
                    listOfProducts[index]['productImage']
                    ,
                    height: 80.0,
                    width: 90.0,
                  ),
                  const SizedBox(
                    height: 15,
                  ),
                  Row(
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            listOfProducts[index]['productName'],
                            style: const TextStyle(
                              fontSize: 15.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          Text(
                            listOfProducts[index]['productCategory'],
                            textAlign: TextAlign.left,
                            style: const TextStyle(
                              height: 1.5,
                              color: kDarkGrey,
                              fontSize: 12.5,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Text(
                        listOfProducts[index]['productPrice'],
                        style: const TextStyle(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const Spacer(),
                      const AddProduct(),
                    ],
                  )
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

但结果是:

我该怎么修复呢?我试了很多方法都没有成功,我不知道是哪部分代码导致了错误?
相关代码片段:

class ImageFiles {
  static File? mobileImage;
  static Uint8List? webImage;
}

class ProductDetails {
  static File? productImage;
  static String? productName;
  static String? productPrice;
}

List<Map<String, dynamic>> listOfProducts = [

];
xjreopfe

xjreopfe1#

由于没有提供stackTrace,我建议使用调试器或print语句来检查mobileImage的值,看看它在哪里变空,您可以在控制台中使用错误stackTrace来跟踪它。
错误的可能原因如下。
您正在使用ImageFiles类的静态属性来存储用户选择的图像。此属性可能会被覆盖。
一个更好的方法是创建类ImageFiles的示例,初始化它_AddNewProductState并将其传递给ProductsListView小部件。
从静态属性切换。

class ImageFiles {
  final File? mobileImage;
  final Uint8List? webImage;

  ImageFiles(this.mobileImages, this.webImage);
}

class ProductDetails {
  final File? productImage;
  final String? productName;
  final String? productPrice;

  ProductDetails(this.productImage, this.productName, this.productPrice);
}

_AddNewProductState中,初始化ImageFile并使用该对象。例如:

class _AddNewProductState extends State<AddNewProduct> {

  /// initialising
  final ImageFiles? imageFiles = ImagesFiles();

  Future<void> openMobileImagePicker() async {
        
        // using imageFiles object
        imageFiles.mobileImage = File(pickedMobileImage.path);
    
  }

现在将此ImageFile传递给任何其他小部件,如GroceryPage,或者根据需要将其添加到listOfProducts中。

相关问题