好久没写了,一直没时间,项目太紧,而且自己也变懒了许多。现在就发一下自己简简单单的封装类吧,一个上传服务器的一个封装。因为很多人问我在选择之后在选择无法去保存上次选择的文件。其实我也没多说什么。就说了一个set去重。在这里我就把我最简单的一个封装拿来用。这里我用的是一个multi_image_picker
这个插件。我也不多说什么了直接上代码了。只要copy下来修改一下自己的网络配置就能使用。
import 'dart:io';
import 'package:---------/pages/login_pages/bloc/uoload_image/upload_repository.dart';
import 'package:---------/utils/file_util.dart';
import 'package:---------/utils/toast_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
/*
* 重新封装图片多选
* 使用直接可以看定义的参数
* */
class WrapMultiImagePicker extends StatefulWidget {
final int maxChoose; //图片最大的选择个数
final Function(List<dynamic> list) callback; //上传服务器接口的回调
final Function(List<dynamic> list) deleteCallback; //删除照片后的回调
const WrapMultiImagePicker(
{Key key,
this.maxChoose = 9,
@required this.callback,
@required this.deleteCallback,
})
: super(key: key);
@override
_WrapMultiImagePickerState createState() => _WrapMultiImagePickerState();
}
class _WrapMultiImagePickerState extends State<WrapMultiImagePicker> {
List<Asset> images = List<Asset>();
List<dynamic> imagesUrlData = [];
bool error = false;
GlobalKey _key = new GlobalKey();
Future<void> loadAssets() async {
List<Asset> resultList = List<Asset>();
try {
resultList = await MultiImagePicker.pickImages(
maxImages: widget.maxChoose,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "选择图片",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
} on Exception catch (e) {
if (mounted) {
setState(() {
error = true;
});
}
}
if (!mounted) return;
setState(() {
Set<Asset> showImages = new Set();
for (var item in resultList) {
showImages.add(item);
}
images = [];
for (var item in showImages) {
images.add(item);
}
_uploadClient();
});
}
// 上传服务器
void _uploadClient() async {
List<String> _imagesUrlList = [];
for (int i = 0; i < images.length; i++) {
ByteData byteData =
await images[i].getByteData(quality: 10); //quality这是一个压缩的比例
String prePath =
await FileUtil.getInstance().getSavePath("/updateImage/");
String name = DateTime.now().millisecondsSinceEpoch.toString() + ".png";
File _imageFile = await File(prePath + name)
.writeAsBytes(byteData.buffer.asUint8List());
if (_imageFile != null) {
_imagesUrlList.add(_imageFile.path);
}
}
final res = await UploadRepository.upMultiFileLoadClient(
imagesUrlList: _imagesUrlList);
if (res["code"] == 0) {
if (widget.callback != null) {
imagesUrlData = res["data"];
widget.callback(imagesUrlData);
}
} else {
T.show(msg: "上传服务器失败,请重新操作");
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 15.w),
child: Container(
width: double.infinity,
child: Wrap(
spacing: 10.w,
runSpacing: 10.h,
children: _showImageWrap(),
),
),
);
}
List<Widget> _showImageWrap(){
List<Widget> tempList = [];
for (int i = 0; i < images.length; i++) {
Asset asset = images[i];
tempList.add(Container(
width: 100,
height: 100,
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: AssetThumb(
asset: asset,
width: 100,
height: 100, //这里的宽高似乎不影响显示的大小
),
),
Positioned(
right: 3,
top: 3,
child: InkWell(
onTap: (){
print("index::::$i");
images.removeAt(i);
imagesUrlData.removeAt(i);
if(widget.deleteCallback != null){
widget.deleteCallback(imagesUrlData);
}
if(mounted){
setState(() {
});
}
},
child: Icon(Icons.cancel,size: 20.ssp,)),
),
],
),
));
}
if (images.length < widget.maxChoose) {
tempList.add(InkWell(
onTap: loadAssets,
child: Container(
key: _key,
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Color(0xffa0a8ac),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.add,
size: 32,
color: Colors.white,
),
SizedBox(
height: 5.h,
),
Text(
"请上传图片",
style: TextStyle(fontSize: 11.ssp, color: Color(0xff333333)),
),
],
),
),
));
}
return tempList;
}
}
import 'dart:io';
import 'package:----------/network_manage/http_utils/http.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
class UploadRepository{
static const _aliyunClientUrl = "你的服务器的地址";
static Future<Map<String,dynamic>> upMultiFileLoadClient({@required List<String> imagesUrlList}) async {
List<MultipartFile> _files = [];
for(var i =0;i < imagesUrlList.length;i++){
final MultipartFile _file = MultipartFile.fromFileSync(imagesUrlList[i]);
if(_file != null){
_files.add(_file);
}
}
Map<String,dynamic> response = await HttpUtil().postUpload(
_aliyunClientUrl,
formData: FormData.fromMap({
"files": _files
}),
options: Options(
receiveTimeout: 200000,
sendTimeout: 200000,
headers: { //上传服务器的头信息
"Content-Type": "multipart/form-data",
}
),
progressCallback: (int count, int total){
print("进度::::${(count * 100 / total).toStringAsFixed(2)}%");
}
);
print("上传阿里云::::$response");
if(response["code"] != 0){
throw Exception(response["msg"] ?? "上传服务器失败");
}
return response;
}
}
由于我这里是先显示的本地然后去用服务器的数据同步自己的操作,这里需要你们自己的服务器是好的。如果上传失败是出现选择后消失的问题,这是因为服务器没上传上去的原因。只要保证接口没问题,这个可以直接拿下来就能用
版权声明:本文为mubowen666原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。