Fluter - пакет выбора изображений: показывать изображения одно за другим с действием удаления - PullRequest
0 голосов
/ 06 марта 2020

В моем проекте Flutter pr я использую плагин Image Picker для выбора изображений из android мобильной галереи или захвата изображений с помощью камеры и показа их одно за другим со значком удаления под каждым изображением. При нажатии RaisedButton для выбора изображений из галереи вызывается метод imageSelectorGallery(). Там внутри метода setState() я добавляю значок SizedBox и delete к List, а именно images_captured. Я ожидаю, что images_captured будет отображаться внутри Column в SingleChildScrollView.

Но после выбора изображения из галереи ничего не происходит. Я также хочу нажать на значок delete и удалить изображение над ним. Но у флаттера нет механизма привязки данных, поскольку я знаю, что коррелировать изображение с кнопкой удаления.

Код следует:

class PrescriptionScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new UserOptionsState();
  }
}

class UserOptionsState extends State<PrescriptionScreen> {
//save the result of gallery fileUserOptions
  File galleryFile;

//save the result of camera file
  File cameraFile;

  @override
  Widget build(BuildContext context) {

    var images_captured=List<Widget>();


    //display image selected from gallery
    imageSelectorGallery() async {
      galleryFile = await ImagePicker.pickImage(
        source: ImageSource.gallery,
        // maxHeight: 50.0,
        // maxWidth: 50.0,
      );
      print("You selected gallery image : " + galleryFile.path);
      setState(() {



        var sized_box_indiv= new SizedBox(
            height: 200.0,
            width: 300.0,
//child: new Card(child: new Text(''+galleryFile.toString())),
//child: new Image.file(galleryFile),
            child:  galleryFile == null
                ? new Text('Sorry nothing selected from gallery!!')
                : new Image.file(galleryFile),

        );
        images_captured.add(sized_box_indiv);

        var delete_button = IconButton(icon: Icon(Icons.delete), onPressed: () {});
        images_captured.add(delete_button);

      });
    }

    //display image selected from camera
    imageSelectorCamera() async {
      cameraFile = await ImagePicker.pickImage(
        source: ImageSource.camera,
        //maxHeight: 50.0,
        //maxWidth: 50.0,
      );
      print("You selected camera image : " + cameraFile.path);
      setState(() {});
    }


          return new SingleChildScrollView(
              child:Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              new RaisedButton(
                child: new Text('Select Image from Gallery'),
                onPressed: imageSelectorGallery,
              ),
              new RaisedButton(
                child: new Text('Select Image from Camera'),
                onPressed: imageSelectorCamera,
              ),

              Column(
                          children: images_captured
                      ),


            ],
          ),
    );
       /* },
      ),
    );*/
  }


}

Q1: Как показывать изображения выбирается из галереи один за другим с иконкой delete под каждым из них?

Q2: Как удалить соответствующее изображение, нажав на иконку delete?

Я думаю, что если я смогу выполнить sh это для галереи, я смогу сделать это и для захвата камеры ....

РЕДАКТИРОВАТЬ: I использовал ответ jJuice, и изображения после выбора показали ошибку переполнения. Скриншот приведен ниже:

enter image description here

Мой код:

class UserOptionsState extends State<PrescriptionScreen> {
//save the result of gallery fileUserOptions
  File galleryFile;

//save the result of camera file
  File cameraFile;
  var images_captured=List<Widget>();

  List<File> images = List<File>();

  @override
  Widget build(BuildContext context) {

    //display image selected from gallery
    imageSelectorGallery() async {



   galleryFile = await ImagePicker.pickImage(
        source: ImageSource.gallery,
        // maxHeight: 50.0,
        // maxWidth: 50.0,
      );

      images.add(galleryFile);
      print("You selected gallery image : " + galleryFile.path);
      setState(() {



      });
    }

    //display image selected from camera
    imageSelectorCamera() async {
      cameraFile = await ImagePicker.pickImage(
        source: ImageSource.camera,
        //maxHeight: 50.0,
        //maxWidth: 50.0,
      );
      print("You selected camera image : " + cameraFile.path);
      setState(() {});
    }



    return new SingleChildScrollView(
      child:Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          new RaisedButton(
            child: new Text('Select Image from Gallery'),
            onPressed: imageSelectorGallery,
          ),
          new RaisedButton(
            child: new Text('Select Image from Camera'),
            onPressed: imageSelectorCamera,
          ),

         new Container(
//            new Column(
//            children: <Widget>[
             height: 1200,
              child:GridView.count(
              crossAxisSpacing: 6,
              mainAxisSpacing: 6,
              crossAxisCount: 3,
              children: List.generate(images.length, (index) {
                return Column(
                    children: <Widget>[
                      Container(
                          height: 200,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(10),
                          ),
                          child: ClipRRect(
                            child: Image.file(images[index], fit: BoxFit.cover),
                            borderRadius: BorderRadius.circular(10),
                          )
                      ),
                      GestureDetector(
                        onTap: () {
                          setState(() {
                            images.removeAt(index);
                          });
                        },
                        child: Padding(
                          padding: const EdgeInsets.all(3.0),
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Icon(Icons.clear, color: Colors.black, size: 20),
                          ),
                        ),
                      ),
                    ]
                );
              }
              ),
            ),
//              ]
          )

          /*displaySelectedFile(galleryFile),
              displaySelectedFile(cameraFile)*/
        ],
      ),
    );



  }

  Widget displaySelectedFile(File file) {
    return new SizedBox(
      height: 200.0,
      width: 300.0,
//child: new Card(child: new Text(''+galleryFile.toString())),
//child: new Image.file(galleryFile),
      child: file == null
          ? new Text('Sorry nothing selected!!')
          : new Image.file(file),
    );
  }
}

1 Ответ

1 голос
/ 06 марта 2020

Вопрос 1: Сначала необходимо сохранить изображения, выбранные с помощью ImagePicker (или плагина MultiImagePicker), в коллекции. Вот пример того, как это сделать:

List<File> images = List<File>(); images.add(await ImagePicker.pickImage(source: ImageSource.gallery, imageQuality: 20););

Когда вы хотите показать эти изображения на экране, вы можете использовать несколько различных виджетов, таких как ListView, GridView, Row, Column , Вот пример, где я использую GridView:

child: Container(
        height: 1200,
        child: GridView.count(
          crossAxisSpacing: 6,
          mainAxisSpacing: 6,
          crossAxisCount: 3,
          children: List.generate(images.length, (index) {
              return Column(
                  children: <Widget>[
                    Container(
                      height: 200,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10),
                      ),
                      child: ClipRRect(
                        child: Image.file(images[index], fit: BoxFit.cover), 
                        borderRadius: BorderRadius.circular(10),
                      )
                    ),
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          images.removeAt(index);
                        });
                      },
                      child: Padding(
                        padding: const EdgeInsets.all(3.0),
                        child: Align(
                          alignment: Alignment.bottomCenter,
                          child: Icon(Icons.clear, color: Colors.white, size: 20),
                        ),
                      ),
                    ),
                  ] 
                ),
            }
        ),
      ),

Я думаю, что использование виджета Stack работает лучше всего в этом случае. Стек можно использовать для отображения виджетов, расположенных друг над другом. Так что в этом случае, виджет, показывающий изображение, с виджетом Icon сверху, который является кнопкой для вашего действия удаления.

Вопрос 2: Вы можете удалить изображение, вызвав метод removeAt, доступный в коллекциях, таких как список. Смотрите код внутри onTap метода GestureDetector. При вызове setState страница восстанавливается после удаления изображения.

РЕДАКТИРОВАТЬ Извините, я неправильно прочитал ваш вопрос и вижу, что вы хотите показать кнопку под изображением вместо на нем. Для этой цели можно использовать виджет Column. Я соответственно отредактировал код.

...