Suman Kumar
Suman Kumar

Reputation: 69

Image is being passed in second attempt not in the first attempt in Flutter

I need some help regarding the image picker plugin in Flutter. When I press image or gallery in the alert dialog and selecting my image, then background image is being displayed but not passed/saved but when I again press image or gallery in the alert dialog and selecting my image, then background image is being both displayed and passed/saved. what should I do?

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

class UserImagePicker extends StatefulWidget {
  UserImagePicker(this.imagePickfn);

  final void Function(File pickedImage) imagePickfn;

  @override
  _UserImagePickerState createState() => _UserImagePickerState();
}

class _UserImagePickerState extends State<UserImagePicker> {
  File _pickedImage;

  void _pickImage() {
    showDialog<ImageSource>(
      context: context,
      builder: (context) =>
          AlertDialog(title: Text("Choose image source"), actions: [
        FlatButton(
          child: Text("Camera"),
          onPressed: () => Navigator.pop(context, ImageSource.camera),
        ),
        FlatButton(
          child: Text("Gallery"),
          onPressed: () => Navigator.pop(context, ImageSource.gallery),
        ),
      ]),
    ).then((ImageSource source) async {
      if (source != null) {
        final pickedFile = await ImagePicker().getImage(
          source: source,
          imageQuality: 50,
          maxWidth: 150,
        );
        setState(() => _pickedImage = File(pickedFile.path));
      }
    });
    widget.imagePickfn(_pickedImage);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        CircleAvatar(
          radius: 40,
          backgroundColor: Theme.of(context).primaryColor,
          backgroundImage:
              _pickedImage != null ? FileImage(_pickedImage) : null,
        ),
        FlatButton.icon(
          textColor: Theme.of(context).primaryColor,
          onPressed: _pickImage,
          icon: Icon(Icons.image),
          label: Text('Add an Image'),
        ),
      ],
    );
  }
}

Upvotes: 1

Views: 515

Answers (1)

Anirban Das
Anirban Das

Reputation: 1265

The problem is in the _pickImage() method. You need to move widget.imagePickfn(_pickedImage); inside then section. Like this.

void _pickImage() {
    showDialog<ImageSource>(
      context: context,
      builder: (context) =>
          AlertDialog(title: Text("Choose image source"), actions: [
        FlatButton(
          child: Text("Camera"),
          onPressed: () => Navigator.pop(context, ImageSource.camera),
        ),
        FlatButton(
          child: Text("Gallery"),
          onPressed: () => Navigator.pop(context, ImageSource.gallery),
        ),
      ]),
    ).then((ImageSource source) async {
      if (source != null) {
        final pickedFile = await ImagePicker().getImage(
          source: source,
          imageQuality: 50,
          maxWidth: 150,
        );
        setState(() => _pickedImage = File(pickedFile.path));
        widget.imagePickfn(_pickedImage);
      }
    });
  }

This is happening because you called the widget.imagePickfn(_pickedImage); method outside the then method. The picked image result is returned in the then section after closing dialog. That is why, in first attempt your image is not returning, and in second attempt it is returning the previous selected image.

Hope this will solve your problem.

If the above one doesn't solve your problem, you can try this one

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

class UserImagePicker extends StatefulWidget {
  UserImagePicker(this.imagePickfn);

  final void Function(File pickedImage) imagePickfn;

  @override
  _UserImagePickerState createState() => _UserImagePickerState();
}

class _UserImagePickerState extends State<UserImagePicker> {
  File _pickedImage;

  void _pickImage() async {
    ImageSource source = await showDialog<ImageSource>(
      context: context,
      builder: (context) =>
          AlertDialog(title: Text("Choose image source"), actions: [
        FlatButton(
          child: Text("Camera"),
          onPressed: () => Navigator.pop(context, ImageSource.camera),
        ),
        FlatButton(
          child: Text("Gallery"),
          onPressed: () => Navigator.pop(context, ImageSource.gallery),
        ),
      ]),
    );
    
    if (source != null) {
      final pickedFile = await ImagePicker().getImage(
        source: source,
        imageQuality: 50,
        maxWidth: 150,
      );
      setState(() => _pickedImage = File(pickedFile.path));
      widget.imagePickfn(_pickedImage);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        CircleAvatar(
          radius: 40,
          backgroundColor: Theme.of(context).primaryColor,
          backgroundImage:
              _pickedImage != null ? FileImage(_pickedImage) : null,
        ),
        FlatButton.icon(
          textColor: Theme.of(context).primaryColor,
          onPressed: () => _pickImage(),
          icon: Icon(Icons.image),
          label: Text('Add an Image'),
        ),
      ],
    );
  }
}

Upvotes: 1

Related Questions