skip to Main Content

I made a form to add an image and its information in a ListView.builder(), this is the image screenshot and code:

enter image description here

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'),),

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


When I tap ‘Submit’ it’s supposed to add the information in a ListView.builder() , this is the image screenshot and code:

enter image description here


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(),
                    ],
                  )
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

But the result is:

enter image description here

How can I fix it? I tried many ways with no success, I don’t know which part of the code causes the error?

Relative code snippets:


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

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


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


];

I hope someone can help me via checking the project repo:

https://github.com/ahmloutfy/Grocery-Store.git 

2

Answers


  1. Since there is no stackTrace provided, I’ll suggest using a debugger or print statements to check the value of mobileImage. See where it’s getting null. You can track it with the error stackTrace in the console.

    A possible reason for the error could be the following.
    You’re using a static property of the ImageFiles class to store the image selected by the user. This property might be getting overridden.

    A better approach would be to create an instance of the class ImageFiles, initialize it _AddNewProductState and pass it to the ProductsListView widget.

    Switching from static properties.

    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);
    }
    

    In _AddNewProductState, initialize the ImageFile and use that object.
    For example:

    class _AddNewProductState extends State<AddNewProduct> {
    
      /// initialising
      final ImageFiles? imageFiles = ImagesFiles();
    
      Future<void> openMobileImagePicker() async {
            
            // using imageFiles object
            imageFiles.mobileImage = File(pickedMobileImage.path);
        
      }
    

    Now pass this ImageFile to any other widget like GroceryPage or add this in the listOfProducts as needed.

    Login or Signup to reply.
  2. 1- Add a variable productImage in _AddNewProductState

    String? productImage;
    

    2- in this method openMobileImagePicker replace this line:

    ImageFiles.mobileImage = File(pickedMobileImage.path);
    

    with this:

    productImage = pickedMobileImage.path;
    

    3- replace this:

    child: CircleAvatar(
                  backgroundImage: (ImageFiles.mobileImage != null)
                  ? Image.file(ImageFiles.mobileImage!, fit: BoxFit.fill).image
                  : null),
    

    with this:

    child: CircleAvatar(
                  backgroundImage: (productImage != null)
                  ? Image.file(File(productImage), fit: BoxFit.fill).image
                  : null),
    

    4- replace this:

    TextFormField(
                                    onSaved: (value) {
                                      setState(() {
                                        ProductDetails.productPrice = value!;
                                      });
                                    },
                                    decoration: const InputDecoration(
                                        labelText: 'Product Price',
                                        hintText: 'Add Product Price'),
                                  ),
    

    with this:

    TextFormField(
                                    onSaved: (value) {
                                      setState(() {
                                        productPrice = value??"";
                                      });
                                    },
                                    decoration: const InputDecoration(
                                        labelText: 'Product Price',
                                        hintText: 'Add Product Price'),
                                  ),
    

    5- replace this:

    TextFormField(
                                    onSaved: (value) {
                                      setState(() {
                                        ProductDetails.productName = value!;
                                      });
                                    },
                                    decoration: const InputDecoration(
                                        labelText: 'Product Name',
                                        hintText: 'Add Product Name'),
                                  ),
    

    with this:

    TextFormField(
                                    onSaved: (value) {
                                      setState(() {
                                        productName = value??"";
                                      });
                                    },
                                    decoration: const InputDecoration(
                                        labelText: 'Product Name',
                                        hintText: 'Add Product Name'),
                                  ),
    

    6- replace this:

    ElevatedButton(
       onPressed: () {
          listOfProducts.add({
            'productImage':ProductDetails.productImage,
            'productName' : ProductDetails.productName,
            'productPrice' : ProductDetails.productPrice,
            'productCategory' : dropdownValue,
            });
    
                    },
      child: const Text('Add Product!'))
    

    with this:

    ElevatedButton(
           onPressed: () {
              listOfProducts.add({
                'productImage':productImage,
                'productName' : productName,
                'productPrice' : productPrice,
                'productCategory' : dropdownValue,
                });
        
                        },
          child: const Text('Add Product!'))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search