c/c++语言开发共享基于Flutter实现图片选择和图片上传

内容简介本篇将介绍 flutter 中如何完成图片上传,以及上传成功后的表单提交。涉及的知识点如下:图片选择插件wechat_assets_picker的使用。图片选择 ios 和安卓的应用权限配置。

内容简介

本篇将介绍 flutter 中如何完成图片上传,以及上传成功后的表单提交。涉及的知识点如下:

  • 图片选择插件wechat_assets_picker的使用。
  • 图片选择 ios 和安卓的应用权限配置。
  • 图片选择组件的封装。
  • 图片上传接口的封装。
  • 添加和编辑页面中图片上传实现。

图片选择插件

flutter 的图片选择插件很多,包括了官方的 image_pickermulti_image_picker(基于2.0出了 multi_image_picker2)等等。为了寻找合适的图片选择插件,找了好几个,发现了一个仿微信的图片选择插件 wechat_assets_picker,看评分和 github的star都不错,先来试用一下。

权限申请

先上了一个简单的 demo,直接调用:

final list<assetentity> assets = await assetpicker.pickassets(context);  

结果发现闪退了!!!难道是插件有bug?

基于Flutter实现图片选择和图片上传

bug.jpg

哦,想起来了!忘记设置图片获取权限了!ios 在 runner 的 info.plist 文件增加如下内容:

<key>nsapptransportsecurity</key>  <dict>    <key>nsallowsarbitraryloads</key>    <true/>  </dict>  <key>nsphotolibraryusagedescription</key>  <string>获取图片及使用相册拍照以便上传动态图片。</string>  

安卓在app/profile/androidmanifest.xml 和 app/debug/androidmanifest.xml 中增加如下内容:

<uses-permission android:name="android.permission.read_external_storage"/>  <uses-permission android:name="android.permission.write_external_storage"/>  <uses-permission android:name="android.permission.access_media_location"/>  

再次运行,完美!我们都是这么跑 demo 的不是?

基于Flutter实现图片选择和图片上传

选择图片.jpg

ui 改造

我们将动态的添加和编辑修改为选择图片的方式,原先的输入框不能用了,需要更改为图片选择,考虑图片选择会经常用,封装一个通用的单图选择组件。

static widget imagepicker(    string formkey,    valuechanged<string> ontapped, {    file imagefile,    string imageurl,    double width = 80.0,    double height = 80.0,  }) {    return gesturedetector(      child: container(        margin: edgeinsets.all(10),        alignment: alignment.center,        decoration: boxdecoration(          color: colors.grey[300],          border: border.all(width: 0.5, style: borderstyle.solid),          borderradius: borderradius.all(radius.circular(4.0)),        ),        child: _getimagewidget(imagefile, imageurl, width, height),        width: width,        height: height,      ),      ontap: () {        ontapped();      },    );  }    static widget _getimagewidget(      file imagefile, string imageurl, double width, double height) {    if (imagefile != null) {      return image.file(        imagefile,        fit: boxfit.cover,        width: width,        height: height,      );    }    if (imageurl != null) {      return cachednetworkimage(        imageurl: imageurl,        fit: boxfit.cover,        width: width,        height: height,      );    }      return icon(icons.add_photo_alternate);  }  

这里考虑图片选择组件的占位图片可能来自网络,也可能是文件,因此做了不同的处理。优先显示文件图片,其次是网络图片,若都没有则显示一个添加图片的图标。

之前的动态表单 dynamic_form.dart 也需要进行相应的调整,包括接收图片参数,图片处理函数,并且将之前的图片文本框改为图片选择组件,点击该组件时调用wechat_assets_picker插件提供的assetpicker.pickassets方法,限制最大可选则图片为1张。

list<widget> _getform(buildcontext context) {    list<widget> widgets = [];    formdata.foreach((key, formparams) {      widgets.add(formutil.textfield(key, formparams['value'],          controller: formparams['controller'] ?? null,          hinttext: formparams['hinttext'] ?? '',          prefixicon: formparams['icon'],          onchanged: handletextfieldchanged,          onclear: handleclear));    });    widgets.add(formutil.imagepicker(      'imageurl',      () {        _pickimage(context);      },      imagefile: imagefile,      imageurl: imageurl,    ));      widgets.add(buttonutil.primarytextbutton(      buttonname,      handlesubmit,      context,      width: mediaquery.of(context).size.width - 20,    ));      return widgets;  }    void _pickimage(buildcontext context) async {    final list<assetentity> assets =        await assetpicker.pickassets(context, maxassets: 1);    if (assets.length > 0) {      file file = await assets[0].file;      handleimagepicked(file);    }  }  

看看效果怎么样?看起来一切正常,接下来看如何上传。

基于Flutter实现图片选择和图片上传

屏幕录制2021-07-10 下午4.51.51.gif

图片上传

图片上传和获取接口之前已经完成,可以先拉取最新的后台代码:基于 expressjs 的后台代码。接口地址分别为:

  • 单张图片上传接口地址:https://localhost:3900/api/upload/image ,post 请求,字段名为image,成功后返回图片文件id
  • 图片获取接口:https://localhost:3900/api/upload/image/:id ,利用图片文件 id 即可获取图片文件流。

dio 提供了formdata的方式上传文件,示例代码如下:

// 单个文件上传  var formdata = formdata.frommap({    'name': 'wendux',    'age': 25,    'file': await multipartfile.fromfile('./text.txt',filename: 'upload.txt')  });  response = await dio.post('/info', data: formdata);  // 多个文件上传  formdata.frommap({    'files': [      multipartfile.fromfilesync('./example/upload.txt', filename: 'upload.txt'),      multipartfile.fromfilesync('./example/upload.txt', filename: 'upload.txt'),    ]  });  

我们可以利用这种方式完成图片的上传。图片上传属于一个公共的服务,我们新建一个 upload_service.dart 文件,用于管理所有上传接口。当前只有一个上传单个文件的方法,从图片文件获取文件路径构建 multipartfile 对象即可,如下所示。

import 'dart:io';    import 'package:dio/dio.dart';    class uploadservice {    static const string uploadbaseurl = 'https://localhost:3900/api/upload/';    static future uploadimage(string key, file file) async {      formdata formdata =          formdata.frommap({key: await multipartfile.fromfile(file.path)});      var result = await dio().post(uploadbaseurl + 'image', data: formdata);        return result;    }  }  

接下来就是处理提交事件了,这里添加和编辑处理逻辑会有些不同:

  • 添加时需要校验图片文件是否为空,为空则提示需要上传文件;
  • 编辑时,本身是一个 原数据的url,若图片文件为空,此时不需要向后台上传图片,也不需要将图片原有的 url上传 (后台代码只存储图片文件的 id,由前端拼接完整地址)。若图片文件不为空,则需要提交数据到后台。如果做得体验更优和节省后端请求,可以比较新表单数据和原表数据是否相同,若没有改变则无需提交数据请求。

提交时,我们需要先上传图片,图片上传成功后将图片文件 id 放入到提交的表单数据里在提交新增或更新接口中。添加时的提交代码如下所示:

_handlesubmit() async {    //其他表单校验    if (_imagefile == null) {      dialogs.showinfo(this.context, '图片不能为空');      return;    }    easyloading.showinfo('请稍候...', masktype: easyloadingmasktype.black);      try {      string imageid;      var imageresponse = await uploadservice.uploadimage('image', _imagefile);      if (imageresponse.statuscode == 200) {        imageid = imageresponse.data['id'];      }      if (imageid == null) {        dialogs.showinfo(this.context, '图片上传失败');        return;      }      map<string, string> newformdata = {};      _formdata.foreach((key, value) {        newformdata[key] = value['value'];      });      //新增时将图片 id 放入提交表单中      newformdata['imageurl'] = imageid;      // 省略提交代码    }    // ...    //省略异常处理代码  }

以上就是基于flutter实现图片选择和图片上传的详细内容,更多关于flutter图片选择上传的资料请关注<计算机技术网(www.ctvol.com)!!>其它相关文章!

需要了解更多c/c++开发分享基于Flutter实现图片选择和图片上传,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/1074188.html

(0)
上一篇 2022年4月7日
下一篇 2022年4月7日

精彩推荐