'Clear the form completely

I have a form that the user can fill out. This form has one text field and one custom field (ImagePickerWidget()) with the ability to add a photo. The custom field is moved to a separate class.

.......
          new Text('What is problem', style: TextStyle(fontSize: 20.0),),
      new TextFormField(decoration: const InputDecoration(
        hintText: 'Describe the problem',),
          validator: (value){if (value!.isEmpty) return 'Please, describe the problem ';}),
      new SizedBox(height: 20.0),

      ImagePickerWidget(),
      new SizedBox(height: 20.0),

      ElevatedButton(
        onPressed: (){if(_formKey.currentState!.validate()) {
          _formKey.currentState?.reset();
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Form completed successfully',
              style: TextStyle(color: Colors.black),),
              backgroundColor: Colors.yellow,));
        }},
        child: const Text('Submit', style: TextStyle(color: Colors.black),),
        style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.yellow)),)
 ......

my custom widget

    class ImagePickerWidget extends StatefulWidget {
      const ImagePickerWidget( {Key? key}) : super(key: key);
    
    
      @override
      State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
    }
    
    class _ImagePickerWidgetState extends State<ImagePickerWidget> {

  late List<CustomImage> images;
  late double size;
  late ImagePicker imagePicker;
  late int idGenerator;

  @override
  void initState() {
    images = [];
    size = 100;
    idGenerator = 0;
    imagePicker = ImagePicker();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              pickImage();
            },
            child: Text('Pick Image')),
        Wrap(
            children: images.map((image) {
              return Stack(children: [
                SizedBox(
                    height: size,
                    width: size,
                    child: ClipRRect(
                        child: Image.memory(
                          image.imageData,
                          fit: BoxFit.fill,
                        ))),
                Positioned(
                    right: 4,
                    top: 4,
                    child: InkWell(
                        onTap: () {
                          //delete image
                          images.removeWhere(
                                  (element) => element.imageData == image.imageData);
                          setState(() {});
                        },
                        child: Container(
                            color: Colors.white, child: Icon(Icons.clear))))
              ]);
            }).toList())
      ],
    );
  }

  Future<void> pickImage() async {
    //XFile? image = await imagePicker.pickImage(source: ImageSource.camera);
    XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      Uint8List imageData = await image.readAsBytes();
      int id = idGenerator++;
      images.add(CustomImage(imageData: imageData, id: id));
      setState(() {});


    }
  }
}

class CustomImage {
  Uint8List imageData;
  int id;

  CustomImage({required this.imageData, required this.id});
}

but the problem is that when the button is pressed 'Submit' only the text field is erased (_formKey.currentState?.reset();), and the selected photos remain in the form. Tell me what should I do so that when I click on the button 'Submit' the whole form is cleared?



Solution 1:[1]

enter image description here

keep the variable outside the class in your imagepick widget

List<CustomImage> images=[];

like this List images=[]; //============look here class _ImagePickerWidgetState extends State {

  late double size;
  late ImagePicker imagePicker;
  late int idGenerator;
      

do like this in your onpressed

  onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    _formKey.currentState?.reset();
                setState(() {
                  images=[];
                });
                    ScaffoldMessenger.of(context)
                        .showSnackBar(const SnackBar(
                      content: Text(
                        'Form completed successfully',
                        style: TextStyle(color: Colors.black),
                      ),
                      backgroundColor: Colors.yellow,
                    ));
                  }
                }

SampleCode

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

ImagePicker? picker;

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  picker = ImagePicker();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MySQL Test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [FormForDeviceService()],
      ),
    );
  }
}

List<File> myfile = [];
List<int> f = [1, 2, 3, 4, 5];
List<bool> fs = [false, false, false, true, true];

class FormForDeviceService extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _FormForDeviceService();
}

class _FormForDeviceService extends State {
  final _formKey = GlobalKey<FormState>();

  Widget build(BuildContext context) {
    return Container(
        padding: const EdgeInsets.all(10.0),
        child: Form(
            key: _formKey,
            child: Column(
              children: <Widget>[
                new Text(
                  'What is problem',
                  style: TextStyle(fontSize: 20.0),
                ),
                new TextFormField(
                    decoration: const InputDecoration(
                      hintText: 'Describe the problem',
                    ),
                    validator: (value) {
                      if (value!.isEmpty)
                        return 'Please, describe the problem ';
                    }),
                new SizedBox(height: 20.0),
                ImagePickerWidget(),
                new SizedBox(height: 20.0),
                ElevatedButton(
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        _formKey.currentState?.reset();
                    setState(() {
                      images=[];
                    });
                        ScaffoldMessenger.of(context)
                            .showSnackBar(const SnackBar(
                          content: Text(
                            'Form completed successfully',
                            style: TextStyle(color: Colors.black),
                          ),
                          backgroundColor: Colors.yellow,
                        ));
                      }
                    },
                    child: const Text(
                      'Submit',
                      style: TextStyle(color: Colors.black),
                    ),
                    style: ButtonStyle(
                        backgroundColor:
                            MaterialStateProperty.all(Colors.yellow)))
              ],
            )));
  }
}

class ImagePickerWidget extends StatefulWidget {
  const ImagePickerWidget({Key? key}) : super(key: key);

  @override
  State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}
 List<CustomImage> images=[];
class _ImagePickerWidgetState extends State<ImagePickerWidget> {

  late double size;
  late ImagePicker imagePicker;
  late int idGenerator;

  @override
  void initState() {
    images = [];
    size = 100;
    idGenerator = 0;
    imagePicker = ImagePicker();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              pickImage();
            },
            child: Text('Pick Image')),
        Wrap(
            children: images.map((image) {
          return Stack(children: [
            SizedBox(
                height: size,
                width: size,
                child: ClipRRect(
                    child: Image.memory(
                  image.imageData,
                  fit: BoxFit.fill,
                ))),
            Positioned(
                right: 4,
                top: 4,
                child: InkWell(
                    onTap: () {
                      //delete image
                      images.removeWhere(
                          (element) => element.imageData == image.imageData);
                      setState(() {});
                    },
                    child: Container(
                        color: Colors.white, child: Icon(Icons.clear))))
          ]);
        }).toList())
      ],
    );
  }

  Future<void> pickImage() async {
    //XFile? image = await imagePicker.pickImage(source: ImageSource.camera);
    XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      Uint8List imageData = await image.readAsBytes();
      int id = idGenerator++;
      images.add(CustomImage(imageData: imageData, id: id));
      setState(() {});
    }
  }
}

class CustomImage {
  Uint8List imageData;
  int id;

  CustomImage({required this.imageData, required this.id});
}

Solution 2:[2]

Try this.

.......
     List<CustomImage> images = [];

      new Text('What is problem', style: TextStyle(fontSize: 20.0),),
      new TextFormField(decoration: const InputDecoration(
      hintText: 'Describe the problem',),
          validator: (value){if (value!.isEmpty) return 'Please, describe the problem ';
      }),
      new SizedBox(height: 20.0),

      ImagePickerWidget(images: []),
      new SizedBox(height: 20.0),

      ElevatedButton(
        onPressed: (){if(_formKey.currentState!.validate()) {
          _formKey.currentState?.reset();
          setState(() {
             images = [];
          });

          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Form completed successfully',
              style: TextStyle(color: Colors.black),),
              backgroundColor: Colors.yellow,));
          }},
        child: const Text('Submit', style: TextStyle(color: Colors.black),),
        style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.yellow)),)
 ......


class ImagePickerWidget extends StatefulWidget {
  const ImagePickerWidget( {Key? key, required this.images}) : super(key: key);

  List<CustomImage> images = [];
    
    
  @override
  State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}
    
class _ImagePickerWidgetState extends State<ImagePickerWidget> {

  late double size;
  late ImagePicker imagePicker;
  late int idGenerator;

  @override
  void initState() {
    size = 100;
    idGenerator = 0;
    imagePicker = ImagePicker();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              pickImage();
            },
            child: Text('Pick Image')),
        Wrap(
            children: widget.images.map((image) {
              return Stack(children: [
                SizedBox(
                    height: size,
                    width: size,
                    child: ClipRRect(
                        child: Image.memory(
                          image.imageData,
                          fit: BoxFit.fill,
                        ))),
                Positioned(
                    right: 4,
                    top: 4,
                    child: InkWell(
                        onTap: () {
                          //delete image
                          widget.images.removeWhere(
                                  (element) => element.imageData == image.imageData);
                          setState(() {});
                        },
                        child: Container(
                            color: Colors.white, child: Icon(Icons.clear))))
              ]);
            }).toList())
      ],
    );
  }

  Future<void> pickImage() async {
    //XFile? image = await imagePicker.pickImage(source: ImageSource.camera);
    XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      Uint8List imageData = await image.readAsBytes();
      int id = idGenerator++;
      widget.images.add(CustomImage(imageData: imageData, id: id));
      setState(() {});


    }
  }
}

class CustomImage {
  Uint8List imageData;
  int id;

  CustomImage({required this.imageData, required this.id});
}

Solution 3:[3]

In the accepted answer you need to keep ImagePickerWidget in the same file where you will be having your form widget. Below is my solution which needs some modification in the ImagePickerWidget only. You could try it if want to have both the widgets in separate files and to have better management.

MAIN WIDGET CODE:

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_memory/image_picker_widget.dart';

void main() {
  runApp(GetMaterialApp(title: 'Flutter', home: Flutter()));
}

class Flutter extends StatefulWidget {
  const Flutter({Key? key}) : super(key: key);

  @override
  State<Flutter> createState() => _FlutterState();
}

class _FlutterState extends State<Flutter> {

  late List<CustomImage> images;
  
  @override
  void initState() {
    super.initState();
    images = [];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(child: Text("Submit"), onPressed: (){
              setState(() {
                images.clear();
              });
            },),
            ImagePickerWidget(images: images,)
          ],
        ),
      ),
    );
  }
}

IMAGE PICKER WIDGET:

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

class ImagePickerWidget extends StatefulWidget {
  List<CustomImage> images;
  ImagePickerWidget({Key? key, required this.images}) : super(key: key);

  @override
  State<ImagePickerWidget> createState() => _ImagePickerWidgetState();
}

class _ImagePickerWidgetState extends State<ImagePickerWidget> {
  late double size;
  late ImagePicker imagePicker;
  late int idGenerator;

  @override
  void initState() {
    widget.images = [];
    size = 100;
    idGenerator = 0;
    imagePicker = ImagePicker();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              print(widget.images.length); //will print the current length of images list
            },
            child: Text('Get Image Length')),
        ElevatedButton(
            onPressed: () {
              pickImage();
            },
            child: Text('Pick Image')),
        Wrap(
            children: widget.images.map((image) {
          return Stack(children: [
            SizedBox(
                height: size,
                width: size,
                child: ClipRRect(
                    child: Image.memory(
                  image.imageData,
                  fit: BoxFit.fill,
                ))),
            Positioned(
                right: 4,
                top: 4,
                child: InkWell(
                    onTap: () {
                      //delete image
                      widget.images.removeWhere(
                          (element) => element.imageData == image.imageData);
                      setState(() {});
                    },
                    child: Container(
                        color: Colors.white, child: Icon(Icons.clear))))
          ]);
        }).toList())
      ],
    );
  }

  Future<void> pickImage() async {
    // XFile? image = await imagePicker.pickImage(source: ImageSource.camera);
    XFile? image = await imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      Uint8List imageData = await image.readAsBytes();
      int id = idGenerator++;
      widget.images.add(CustomImage(imageData: imageData, id: id));
      setState(() {});
    }
  }
}

class CustomImage {
  Uint8List imageData;
  int id;

  CustomImage({required this.imageData, required this.id});
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 lava
Solution 2 Zakaria Hossain
Solution 3 Ankit Kumar Maurya