简体   繁体   中英

Get images working in a listview in flutter

I have a problem getting images using imagePicker to work in a listview. When you press one of the containers in the listview you should be able to choose an image from the gallery. This works the first time but then I get a RangeError (index) Invalid value: Only valid value 0: 1 on the rest of the boxes (se the images down below). I am as you can see trying to use the index to check if the element has any data but I dont think Im getting it right. Any suggestions code examples please!

Future _getImage() async {
    final image = await ImagePicker().pickImage(source: ImageSource.gallery);
    setState(() {
      //_image = image;
      _imageList.add(image!);

      //print('first element: ${_imageList!.isEmpty}');
      //print('second element: ${_imageList!.}');
    });
  }
   

 Padding(
                    padding: const EdgeInsets.symmetric(
                        vertical: 20.0, horizontal: 20.0),
                    child: Container(
                      height: 130.0,
                     
    
                    child: ListView.separated(
                          separatorBuilder: (context, index) => SizedBox(
                                width: 5.0,
                              ),
                          scrollDirection: Axis.horizontal,
                          itemCount: 5,
                          itemBuilder: (BuildContext context, int index) {
                            
                            return _imageList?.isEmpty ?? true
                                ? GestureDetector(
                                    onTap: _getImage,
                                    child: Container(
                                      height: 40.0,
                                      width: 150.0,
                                      decoration: BoxDecoration(
                                        border: Border.all(color: Colors.grey),
                                      ),
                                      child: Center(
                                          child: Text('Image ${num = index + 1}')),
                                    ))
                                : GestureDetector(
                                    child: Container(
                                        height: 40.0,
                                        width: 150.0,
                                        decoration: BoxDecoration(
                                          border: Border.all(color: Colors.grey),
                                        ),
                                        child: Image.file(
                                          File(_imageList[index].path),
                                          fit: BoxFit.cover,
                                        )));
                          }),
                    )),

在此处输入图像描述

在此处输入图像描述

You're loading 5 list of items. Once you pick an image your imageList will not be empty and Once your imageList isn't empty, then it'll try to display list of images with indexes. Since you've picked 1 image in imageList and you can only display imageList[0]. Since imageList[index] tries to access other indexes and you don't have items on those indexes, it'll throw Range Error.

There are other ways of doing this but in my case, I'm doing this. Create an extension function on all iterable types globally in your code. Declare it outside main function or in a separate file. If the item at index exists, it'll return you the item else null.

extension ItemAtIndexOrNull<T> on Iterable<T> {
  itemAtIndexOrNull(int index) {
try {
  final data = this.elementAt(index);
  return data;
} catch (e) {
  return null;
}

} }

And Now replace your _imageList?.isEmpty?? true with _imageList.itemAtIndexOrNull(index) == null

You have set the itemCount to 5, instead use a list of null. And you can check the item at an index is null or type of File. If its file then item is loaded else not.

    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
 
   class ListImages extends StatefulWidget {
     @override
     _ListImagesState createState() => _ListImagesState();
     }
    class _ListImagesState extends State<ListImages> {
      Future _getImage() async {
        final image = await ImagePicker().pickImage(source: ImageSource.gallery);
        setState(() {
          //_image = image;
          images.add(image!);
    
          //print('first element: ${_imageList!.isEmpty}');
          //print('second element: ${_imageList!.}');
        });
      }
    
      final List<XFile?> images = List<XFile?>.filled(5, null);
    
      @override
      Widget build(BuildContext context) {
        return ListView.separated(
          separatorBuilder: (context, index) => SizedBox(
            width: 5.0,
          ),
          scrollDirection: Axis.horizontal,
          itemCount: images.length,
          itemBuilder: (BuildContext context, int index) {
            XFile? file = images[index];
            return GestureDetector(
              onTap: file == null ? _getImage : null,
              child: Container(
                height: 40.0,
                width: 150.0,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey),
                ),
                child: file == null
                    ? Center(child: Text('Image ${index + 1}'))
                    : Image.file(
                        File(images[index]!.path),
                        fit: BoxFit.cover,
                      ),
              ),
            );
          },
        );
      }
    }
        

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM