Работа с зависимостью средства выбора тепловизора во Flutter

В моем приложении есть функция, которая помогает пользователю выбрать изображение из галереи или сделать снимок с помощью камеры.

  _getImage(ImageSource source) async {
    // ignore: deprecated_member_use
    File selectedImage = await ImagePicker.pickImage(
      source: source,
      imageQuality: 50,
      maxWidth: 400.0,
    ).whenComplete(() {
      setState(() {});
    });
    if (_imageFile == null) return;
    
    setState(() {
      _imageFile = selectedImage;
    });
  }

Я использую эту зависимость image_picker, и я следовал примеру, который я нашел в нем, а также примерам возможных обновлений, выполненных другие онлайн. Из предложения по этому вопросу о переполнении стека, мне советуют добавить в него whenComplete, что я и сделал.

Когда я выбираю изображение из своей галереи, оно не обновляет виджет просмотра изображений на моем экране. Также не работает опция камеры. Что я мог упустить?

Вот мой виджет Image, который отображает изображение:

return Stack(
    alignment: AlignmentDirectional.bottomCenter,
    children: <Widget>[
      Image.file(
        _imageFile,
        fit: BoxFit.cover,
        height: 250,
      ),
      Container(
        width: 250.0,
        height: 100.0,
        color: Colors.black54,
        child: Column(
          children: <Widget>[
            Text(
              'Change Image',
              style: TextStyle(
                color: Colors.white,
                fontSize: 22.0,
                fontWeight: FontWeight.w400,
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                //camera button
                IconButton(
                  icon: Icon(FontAwesomeIcons.camera),
                  onPressed: () => _getImage(ImageSource.camera),
                  color: kThemeStyleButtonFillColour,
                ),
                SizedBox(width: 20.0),
                IconButton(
                  icon: Icon(FontAwesomeIcons.fileImport),
                  onPressed: () => _getImage(ImageSource.gallery),
                  color: kThemeStyleButtonFillColour,
                ),
              ],
            ),
          ],
        ),
      ),
      SizedBox(height: 32.0),
    ],
  );

person hermie_brown    schedule 27.09.2020    source источник
comment
Прежде всего, прекратите использовать pickImage, поскольку он устарел. Используйте final pickedFile = ImagePicker().getImage(source: ImageSource.camera);, это возвращает pickedFile и может быть преобразовано в файл с помощью imageFile = File(pickedFile.Path)   -  person ASAD HAMEED    schedule 27.09.2020
comment
Поделитесь фрагментом кода, который содержит Image widget и объявление _imageFile переменной.   -  person ASAD HAMEED    schedule 27.09.2020
comment
getImage у меня не работает, так как он хочет, чтобы я преобразовал его как файл. Только pickImage делает это, хотя и говорит, что устарел, поэтому я подавляю предупреждения. Это ошибка, которую выдает getImage (): значение типа «PickedFile» не может быть присвоено переменной типа «файл».   -  person hermie_brown    schedule 28.09.2020
comment
Я отредактировал свой вопрос, добавив виджет изображения, который его отображает.   -  person hermie_brown    schedule 28.09.2020
comment
Нашел проблему, проверьте мой ответ, надеюсь, это решит вашу проблему. ????   -  person ASAD HAMEED    schedule 28.09.2020


Ответы (4)


Вы используете неправильную логику внутри оператора if.

Правильный способ сделать это,

if(selectedImage != null) { Update image widget here }

Я думаю, что переменной imageFile изначально не был назначен какой-либо файл, поэтому условие imageFile == null всегда истинно, а виджет изображения никогда не обновляется.

person ASAD HAMEED    schedule 28.09.2020

** Я обновлю ваш код, попробуйте это **

import 'package:image_picker/image_picker.dart';

class check extends StatefulWidget {
  @override
  _checkState createState() => _checkState();
}

class _checkState extends State<check> {
  File _imageFile;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Stack(
      alignment: AlignmentDirectional.bottomCenter,
      children: <Widget>[
        _imageFile !=null ? Image.file(
          _imageFile ,
          height: 250,
          fit: BoxFit.fill,
        ) : Text('No image selected.'),
        SizedBox(height: 100,),
        Container(
          width: 250.0,
          height: 100.0,
          color: Colors.black54,
          child: Column(
            children: <Widget>[
              Text(
                'Change Image',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 22.0,
                  fontWeight: FontWeight.w400,
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  //camera button
                  IconButton(
                    icon: Icon(Icons.camera),
                    onPressed: () => _getImage(ImageSource.camera),
                  ),
                  SizedBox(width: 20.0),
                  IconButton(
                    icon: Icon(Icons.attach_file),
                    onPressed: () => _getImage(ImageSource.gallery),

                  ),
                ],
              ),
            ],
          ),
        ),
        SizedBox(height: 32.0),
      ],
    )
    );
  }

  _getImage(ImageSource source) async {
    // ignore: deprecated_member_use
    File selectedImage = await ImagePicker.pickImage(
      source: source,
      imageQuality: 50,
      maxWidth: 400.0,
    );

    setState(() {
      _imageFile = selectedImage;
    });
  }
}
person Mr vd    schedule 28.09.2020

В твоем случае,

   setState(() {
      _imageFile = selectedImage;
    });

Не ждет выбранное изображение

Попробуй это:

   _getImage(ImageSource source) async {
    // ignore: deprecated_member_use
    File selectedImage = await ImagePicker.pickImage(
      source: source,
      imageQuality: 50,
      maxWidth: 400.0,
    );
    setState(() {
         _imageFile = selectedImage;
     });
  }
person Claudio Castro    schedule 27.09.2020
comment
Я пробовал это, и это тоже не работает. Потому что мы не можем присвоить selectedImage значение, когда оно не завершено. Поэтому я сначала объявил его как File selectedImage; затем я использовал selected Image = await ....... Но я все еще не могу изменить изображение на дисплее. - person hermie_brown; 28.09.2020
comment
Если вы используете await, вам не нужно использовать его после завершения. Я обновлю код. - person Claudio Castro; 28.09.2020
comment
Ты прав. whenComplete больше не имеет смысла, если я жду. Однако это еще не волшебство. Тестирую на iPhone 11 Pro. Я наконец заставил его работать, изменив тип selectedImage с File на var. Не имеет смысла, но это то, что сделало. - person hermie_brown; 28.09.2020

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

Я последовал приведенной выше рекомендации, отказавшись от whenComplete, поскольку есть ожидание.

Я также изменил тип объявления selectedImage с File на var, как показано ниже:

  _getImage(ImageSource source) async {
    var selectedImage;
    selectedImage = await ImagePicker.pickImage(
      source: source,
      imageQuality: 50,
      maxWidth: 400.0,
    );

    setState(() {
      _imageFile = selectedImage;
    });
  }

Не имеет смысла, почему var сработал, а File - нет, поскольку мы знаем, что ожидаем, что возвращаемое значение будет File, но сейчас это работает хорошо.

person hermie_brown    schedule 28.09.2020
comment
Я думаю, проблема заключалась в том, что вы использовали предыдущий оператор if, потому что условие не имело никакого смысла. Я также рекомендовал бы заменить pickImage на getImage, прочтите документы для помощи. Для этого обновления есть раздел в документации pub.dev/packages/image_picker - person ASAD HAMEED; 28.09.2020
comment
Да ты прав, спасибо. Я просто прочитал документы и нашел рекомендуемый способ использования getImage. Спасибо! - person hermie_brown; 28.09.2020