【问题标题】:Image is not getting Updated even after using setState In Flutter即使在 Flutter 中使用 setState 后,图像也没有更新
【发布时间】:2020-08-23 17:36:11
【问题描述】:

我正在使用 ImagePicker 和 ImageCropper 包从图库中挑选和裁剪图像,或者使用相机拍摄。一切正常,但即使在使用 SetState 方法后,拾取的图像也没有在 UI 上更新。当我再次按下图像选择按钮时,先前选择的图像出现在 UI 上。我不知道是什么导致了这种延迟。

我的 ImageProcessing 类代码

class ImageProcess{
  File _image, croppedFile;
  final picker = ImagePicker();
  //Getting Image From Gallery Or Camera.
  File getImage(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(15))),
            content: Container(
                height: 250,
                width: 250,
                child: Row(
                  children: [
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.insert_photo),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.gallery,imageQuality: 20);
                          _image = File(pickedFile.path);
                        croppedFile = await _cropImage();
                          Navigator.of(context).pop(true);
                        }),
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.camera),
                        onPressed: () async {
                          final pickedFile =
                          await picker.getImage(source: ImageSource.camera,imageQuality: 20);
                          _image = File(pickedFile.path);
                       croppedFile =  await _cropImage();
                          Navigator.of(context).pop(true);
                        })
                  ],
                )),
          );
        });
    return croppedFile;
  }

  //Cropping image which has been retrieved from gallery or gallery.
  Future<File> _cropImage() async {
   return await ImageCropper.cropImage(
        sourcePath: _image.path,
        aspectRatioPresets: Platform.isAndroid
            ? [
          CropAspectRatioPreset.square,
        ]
            : [
          CropAspectRatioPreset.square,
        ],
        androidUiSettings: AndroidUiSettings(
            toolbarTitle: 'Product Image Cropper',
            toolbarColor: kDarkYellow,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.square,
            lockAspectRatio: false),
        iosUiSettings: IOSUiSettings(
          title: 'Product Image Cropper',
        ));
  }
}

用户界面代码

class AddItem extends StatefulWidget {
  @override
  _AddItemState createState() => _AddItemState();
}

class _AddItemState extends State<AddItem> {
  File croppedFile;
  ImageProcess im = new ImageProcess();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          backgroundColor: kVeryDarkBlue,
          body: SingleChildScrollView(
              child: Padding(
                padding: EdgeInsets.fromLTRB(20, 20, 20, 0),
                child: Column(
                  children: [
                    Container(
                        height: MediaQuery.of(context).size.height * 0.15,
                        width: MediaQuery.of(context).size.height * 0.15,
                        child: croppedFile == null
                            ? ClipOval(
                            child:
                            Image.asset('assets/images/image.png'))
                            : ClipOval(child: Image.file(croppedFile))),
                    RaisedButton(onPressed: () {
                        croppedFile= im.getImage(context);
                        setState(() {
                        });
                    },child: Text('Press'),)
                  ],
                ),
              ))),
    );
  }
}

我已经尝试了所有可能出现在我脑海中的解决方案。

【问题讨论】:

  • 您需要在 getImage 方法中使用 Future。没有他,你的 setstate 会在你得到图像之前更新 ui。
  • 你能给我举个例子吗?

标签: flutter dart state setstate


【解决方案1】:

在您的 getImage 方法中添加 Future 并进行一些调整。

import 'dart:io';

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: AddItem(),
    );
  }
}

class AddItem extends StatefulWidget {
  @override
  _AddItemState createState() => _AddItemState();
}

class _AddItemState extends State<AddItem> {
  File croppedFile;
  ImageProcess im = new ImageProcess();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          backgroundColor: Colors.blue,
          body: SingleChildScrollView(
              child: Padding(
            padding: EdgeInsets.fromLTRB(20, 20, 20, 0),
            child: Column(
              children: [
                Container(
                    height: MediaQuery.of(context).size.height * 0.15,
                    width: MediaQuery.of(context).size.height * 0.15,
                    child: croppedFile == null
                        ? ClipOval(
                            child: Image.asset('assets/images/image.png'))
                        : ClipOval(child: Image.file(croppedFile))),
                RaisedButton(
                  onPressed: () async {
                    // Add await here
                    croppedFile = await im.getImage(context);
                    setState(() {});
                  },
                  child: Text('Press'),
                )
              ],
            ),
          ))),
    );
  }
}

class ImageProcess {
  File _image, croppedFile;
  final picker = ImagePicker();
  //Getting Image From Gallery Or Camera.
  // now getImage is a future that wait for your choice.
  Future<File> getImage(BuildContext context) async {
    return await showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(15))),
            content: Container(
                height: 250,
                width: 250,
                child: Row(
                  children: [
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.insert_photo),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.gallery, imageQuality: 20);
                          _image = File(pickedFile.path);
                          croppedFile = await _cropImage();
                          // croppedFile is the return of your ShowDialog
                          Navigator.of(context).pop(croppedFile);
                        }),
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.camera),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.camera, imageQuality: 20);
                          _image = File(pickedFile.path);
                          croppedFile = await _cropImage();
                          // croppedFile is the return of your ShowDialog
                          Navigator.of(context).pop(croppedFile);
                        })
                  ],
                )),
          );
        });
  }

  //Cropping image which has been retrieved from gallery or gallery.
  Future<File> _cropImage() async {
    return await ImageCropper.cropImage(
        sourcePath: _image.path,
        aspectRatioPresets: Platform.isAndroid
            ? [
                CropAspectRatioPreset.square,
              ]
            : [
                CropAspectRatioPreset.square,
              ],
        androidUiSettings: AndroidUiSettings(
            toolbarTitle: 'Product Image Cropper',
            toolbarColor: Colors.yellow,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.square,
            lockAspectRatio: false),
        iosUiSettings: IOSUiSettings(
          title: 'Product Image Cropper',
        ));
  }
}

【讨论】:

    【解决方案2】:

    在调整了几行之后,我发现问题出在哪里了。

    UI 中 RaisedButton 的代码

    RaisedButton(
                      onPressed: () {
                        showDialog(
                            context: context,
                            builder: (context) {
                              return AlertDialog(
                                shape: RoundedRectangleBorder(
                                    borderRadius:
                                        BorderRadius.all(Radius.circular(15))),
                                content: Container(
                                    height: 250,
                                    width: 250,
                                    child: Row(
                                      children: [
                                        IconButton(
                                            iconSize: 100,
                                            icon: Icon(Icons.insert_photo),
                                            onPressed: () async {
                                              croppedFile =
                                                  await im.getImageGallery();
                                              setState(() {});
                                              Navigator.pop(context);
                                            }),
                                        IconButton(
                                            iconSize: 100,
                                            icon: Icon(Icons.camera),
                                            onPressed: () async {
                                              croppedFile =
                                              await im.getImageCamera();
                                              setState(() {});
                                              Navigator.pop(context);
                                            })
                                      ],
                                    )),
                              );
                            });
                      },
                      child: Text('Press'),
                    )
    

    图像处理类的代码。我把大函数分成了两个子函数。

      //Getting Image From Camera.
      Future<File> getImageCamera() async{
        final pickedFile = await picker.getImage(
            source: ImageSource.camera,imageQuality: 20);
        _image = File(pickedFile.path);
        return _cropImage();
      }
      //Getting Image From Gallery
      Future<File> getImageGallery() async{
        final pickedFile = await picker.getImage(
            source: ImageSource.gallery,imageQuality: 20);
        _image = File(pickedFile.path);
        return _cropImage();
      }
    

    【讨论】:

      猜你喜欢
      • 2020-12-07
      • 2021-01-23
      • 1970-01-01
      • 2020-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多