houba
houba

Reputation: 536

type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>' - Image Picker problem

I need to add an image in a Container. The image is coming from IMAGE PICKER. Im getting the error:

 type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>'

Here's the original code:

                                      Container( //<-- HEADER CONTAINER
                                        height: kHeaderHeight,
                                        width: kHeaderWidth,
                                        decoration:
                                        BoxDecoration(
                                          image: DecorationImage(
                                            image:
                                            _imageFileForHeader.path != null?
                                            FutureBuilder(
                                                future: _getLocalFile(_imageFileForHeader.path),
                                                builder: (BuildContext context, AsyncSnapshot<io.File>  snapshot)
                                                {
                                                  return Image.file(snapshot.data);
                                                }
                                            ):
                                                NetworkImage(urlImage + _kHeaderImage),  fit: BoxFit.cover,
                                          ),
                                        ),

I really could do with any help here.

If the user does not select an image from the gallery - then use the image in the URL (urlImage).

I think I'm doing a very standard routine, and I cannot see why its not working.

Thanks

-- I just want to add that I tried also :

return FileImage(snapshot.data) 

and this did not work either.

I think I exhausted every permutation possible here.

By the way, here's the _getLocalFile...

  Future<io.File> _getLocalFile(String filename) async
  {
    io.File f = new io.File(filename);
    return f;
  }

Upvotes: 1

Views: 602

Answers (2)

Claudio Redi
Claudio Redi

Reputation: 68400

You don't need any future in _getLocalFile as there is no async operations inside. You can just do

return Container( //<-- HEADER CONTAINER
    height: kHeaderHeight,
    width: kHeaderWidth,
    decoration:
    BoxDecoration(
        image: DecorationImage(
        image: _imageFileForHeader?.path != null
                ? Image.file(File(_imageFileForHeader.path)) 
                : Image.network(urlImage + _kHeaderImage);
        ),
    ),

Or Assuming _imageFileForHeader is already a file we could simplify this even more

return Container( //<-- HEADER CONTAINER
    height: kHeaderHeight,
    width: kHeaderWidth,
    decoration:
    BoxDecoration(
        image: DecorationImage(
        image: _imageFileForHeader != null
                ? Image.file(_imageFileForHeader) 
                : Image.network(urlImage + _kHeaderImage);
        ),
    ),

Upvotes: 2

Paul Gro&#223;
Paul Gro&#223;

Reputation: 247

I think your _getLocalFile function returns the wrong datatype. Maybe if you try the following:

Future<File> _getLocalFile() async{
  final ImagePicker _picker = ImagePicker();
  PickedFile pickedFile= await _picker.getImage(source: ImageSource.gallery);
  File file =  File(pickedFile.path);
  return file;
}

Futhermore, I don´t belive that you can use a FutureBuilder for the Containers image variable. To display a image inside a Container you can use:

File file;

Container(
  decoration: new BoxDecoration(
    image: new DecorationImage(
      fit: BoxFit.cover,
      image: new FileImage(file),
    ),
  ),
),

So I think you have to check the file variable for null and if it is null, maybe show a button. If the user presses the button, you can call the async _getLocalFile function and than maybe update with setState to show the image.

Maybe you could also wrap the image around a FutureBuilder:


    FutureBuilder<File>(
        future: _getLocalFile(),
        builder: (BuildContext context, AsyncSnapshot<File>  snapshot)
        {
          if(!snapshot.hasData){
            return CircularProgressIndicator();
          }else{
            return Container(
              decoration: new BoxDecoration(
                image: new DecorationImage(
                  fit: BoxFit.cover,
                  image: new FileImage(snapshot.data),
                ),
              ),
            );
          }
        }
    );

Upvotes: 1

Related Questions