【问题标题】:How can I make multiple image picker which upload and set image inside container in flutter?如何制作多个图像选择器,在颤动中上传和设置容器内的图像?
【发布时间】:2019-09-10 04:51:08
【问题描述】:

我想制作这种类型的图像选择器,当我点击加号时,它会在我选择适合此容器的图像时打开图像选择器。

这是我尝试过的一些代码。

在这段代码中,我使用了平面按钮,它将拾取图像并将其显示在平面按钮下。但我想要像我在图片中提到的那样输出。 5 种不同的图片上传器。

import 'dart:io';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'package:image_picker/image_picker.dart';

class BusinessProfilePage extends StatefulWidget {


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

class _BusinessProfilePageState extends State<BusinessProfilePage> {
  Future<File> profilepicture;
  bool aggreeandaccept = false;
  bool accepttudo = false;

  pickprofilepicture(ImageSource source) {
    setState(() {
      profilepicture = ImagePicker.pickImage(source: source);
    });
  }

  Widget _buildbusinessprofilepicture() {
    return new FormField(
      builder: (FormFieldState state) {
        return FlatButton.icon(
          icon: Icon(Icons.image),
          label: Text('Business Profile Picture'),
          //color: Colors.white,
          textColor: Colors.black54,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(50),
          ),
          onPressed: () {
            pickprofilepicture(ImageSource.gallery);
          },
        );
      },
    );
  }

  Widget _buildprofileimage() {
    return FutureBuilder<File>(
      future: profilepicture,
      builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
        if (snapshot.connectionState == ConnectionState.done &&
            snapshot.data != null) {
          return Image.file(
            snapshot.data,
            width: 100,
            height: 100,
          );
        } else if (snapshot.error != null) {
          return const Text(
            'Error Picking Image',
            textAlign: TextAlign.center,
          );
        } else {
          return const Text(
            'No Image Selected',
            textAlign: TextAlign.center,
          );
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("BusinessProfile"),
      ),
      body: Container(
        height: double.infinity,
        width: double.infinity,
        child: Stack(
          children: <Widget>[
            SingleChildScrollView(
              child: SafeArea(
                top: false,
                bottom: false,
                child: Form(
                  child: Scrollbar(
                    child: SingleChildScrollView(
                      dragStartBehavior: DragStartBehavior.down,
                      padding: const EdgeInsets.symmetric(horizontal: 16.0),
                      child: new Container(
                        margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
                        child: new Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            _buildbusinessprofilepicture(),
                            _buildprofileimage(),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    您可以使用列表轻松实现此目的,我已经为您创建了示例代码,请查看。

    import 'package:blog_app/models/ImageUploadModel.dart';
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    
    class SingleImageUpload extends StatefulWidget {
      @override
      _SingleImageUploadState createState() {
        return _SingleImageUploadState();
      }
    }
    
    class _SingleImageUploadState extends State<SingleImageUpload> {
      List<Object> images = List<Object>();
      Future<File> _imageFile;
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        setState(() {
          images.add("Add Image");
          images.add("Add Image");
          images.add("Add Image");
          images.add("Add Image");
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new Scaffold(
            appBar: new AppBar(
              centerTitle: true,
              title: const Text('Plugin example app'),
            ),
            body: Column(
              children: <Widget>[
            Expanded(
              child: buildGridView(),
            ),
          ],
        ),
      ),
    );
      }
    
      Widget buildGridView() {
        return GridView.count(
      shrinkWrap: true,
      crossAxisCount: 3,
      childAspectRatio: 1,
      children: List.generate(images.length, (index) {
        if (images[index] is ImageUploadModel) {
          ImageUploadModel uploadModel = images[index];
          return Card(
            clipBehavior: Clip.antiAlias,
            child: Stack(
              children: <Widget>[
               Image.file(
                  uploadModel.imageFile,
                  width: 300,
                  height: 300,
                ),
                Positioned(
                  right: 5,
                  top: 5,
                  child: InkWell(
                    child: Icon(
                      Icons.remove_circle,
                      size: 20,
                      color: Colors.red,
                    ),
                    onTap: () {
                      setState(() {
                        images.replaceRange(index, index + 1, ['Add Image']);
                      });
                    },
                  ),
                ),
              ],
            ),
          );
        } else {
          return Card(
            child: IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                _onAddImageClick(index);
              },
            ),
          );
        }
      }),
    );
      }
    
      Future _onAddImageClick(int index) async {
    setState(() {
      _imageFile = ImagePicker.pickImage(source: ImageSource.gallery);
      getFileImage(index);
    });
      }
    
      void getFileImage(int index) async {
    //    var dir = await path_provider.getTemporaryDirectory();
    
    _imageFile.then((file) async {
      setState(() {
        ImageUploadModel imageUpload = new ImageUploadModel();
        imageUpload.isUploaded = false;
        imageUpload.uploading = false;
        imageUpload.imageFile = file;
        imageUpload.imageUrl = '';
        images.replaceRange(index, index + 1, [imageUpload]);
      });
     });
     }
     }
    

    ImageUploadModel 类

    class ImageUploadModel {
      bool isUploaded;
      bool uploading;
     File imageFile;
      String imageUrl;
    
      ImageUploadModel({
        this.isUploaded,
        this.uploading,
        this.imageFile,
        this.imageUrl,
      });
    }
    

    【讨论】:

    • 您好,感谢您的回答,但它会显示错误。错误是这样的:uses-sdk:minSdkVersion 16 不能小于库中声明的版本 19 [:multi_image_picker]
    • 在 android 中打开 build.gradle 文件并将 minSdkVersion 16 更改为 minSdkVersion 19
    • 亲爱的,添加此 minSdkVersion 后,我收到此错误:D8:程序类型已存在:android.support.v4.app.INotificationSideChannel
    • 你也可以用ImagePicker代替MultiImagePIcker,只要去掉multi image picker,改成imagepicker即可
    • 别忘了 import 'dart:io';否则你会得到 Type 'File' not found 错误。
    【解决方案2】:

    你可以使用file_picker插件。

    它支持所有平台,最适合在 Flutter 中拾取文件/字节/图像/视频/等... 这是github的工作演示

    【讨论】:

      【解决方案3】:

      您可以制作 4 个自定义按钮(使用 InkWell/GestureDetector),在他们的 onTap 中,您可以对所有按钮使用类似这样的逻辑:

      // when button 1 is pressed, you go to image picker page, 
      // select image from there and when you come back you update _image1 
      Navigator.push(context, MaterialPageRoute(builder: (_) => ImagePickerPage())).then((pickedImage) {
        if (pickedImage != null) {
          setState(() {
            _image1 = pickedImage;
          });
        }
      });
      

      在您的图像选择器页面中,您需要将图像传回,您会使用

      Navigator.pop(context, pickedImage);
      

      【讨论】:

      • 感谢您的回答,但我需要这种类型的 UI 设计在我想挑选图像的设计中,并且该图像必须适合这些容器。
      • 一旦你有了pickedImage,你就可以在Container里面使用child:pickedImage,应该不难。
      • 你能帮我编码吗?请这是我的要求。因为我非常陷入另一个问题,请你帮我做这件事。希望你能理解 :)。将不胜感激。
      • @RutvikGumasana 我当然可以帮助你,但我不确定你使用哪个插件来挑选图像,而且你也没有共享任何代码,如果你可以共享一个最小的拾取图像代码(您正在使用的那个),我的工作将变得轻松
      • 我已经附上了问题的代码,请检查它并帮助我摆脱这个问题。 :)
      【解决方案4】:

      希望你能帮助这个multi image picker你可以使用这个依赖来集成它。

      【讨论】:

      • 感谢您的回答,但我需要这种类型的 UI 设计在我想挑选图像的设计中,并且该图像必须适合这些容器。
      猜你喜欢
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 2020-05-05
      • 2020-05-26
      相关资源
      最近更新 更多