web-dev-qa-db-fra.com

Comment télécharger plusieurs images à l'aide de Dio et du plugin multi_image_picker dans Flutter

Je souhaite télécharger plusieurs images à l'aide de Dio et du plug-in multi_image_picker dans Flutter.

List<Asset> c'est le problème car je ne peux pas convertir à partir de List<Asset> à List<File> donc si vous avez des solutions, aidez-moi.

essayez d'utiliser:

  1. multi_image_picker: ^4.6.1

  2. dio: ^3.0.4

Merci

Bona SR.

import 'Dart:io';
import 'package:dio/dio.Dart';
import 'package:flutter/material.Dart';
import 'package:flutter_secure_storage/flutter_secure_storage.Dart';
import 'package:merchantside/helper/colorhelper.Dart';
import 'package:merchantside/merchantside/login.Dart';
import 'Dart:async';
import 'package:multi_image_picker/multi_image_picker.Dart';

class ListImages extends StatefulWidget {
  String errorMessage = "";
  @override
  _ListImagesState createState() => new _ListImagesState();
}

class _ListImagesState extends State<ListImages> {
  List<Asset> images = List<Asset>();
  List<File> listImages = [];
  @override
  void initState() {
    super.initState();
  }

  Widget buildGridView() {
    return GridView.count(
      crossAxisCount: 3,
      children: List.generate(images.length, (index) {
        Asset asset = images[index];
        return AssetThumb(
          asset: asset,
          width: 300,
          height: 300,
        );
      }),
    );
  }


  void _uploadFiles() async {
    String uid = await FlutterSecureStorage().read(key: "getTocken");
    try {
      var dio = Dio();
      FormData formData = new FormData.fromMap({
        "pictures[]": images, 
      });
      Response resp = await dio.post(
        mainUrl + 'merchant/upload-galleries',
        data: formData,
        onSendProgress: (int sent, int total) {
          //
        }, 
        options: Options(
          headers: {
            HttpHeaders.authorizationHeader: uid,
          },
        )
      );
      if(resp.statusCode == 200) {
        print("============= Print Resp data: ");
        print(resp.data);
      }

    } catch (e) {
      print(e);
    }
  }

  Future<void> loadAssets() async {
    List<Asset> resultList = List<Asset>();
    try {
      resultList = await MultiImagePicker.pickImages(
        maxImages: 6,
        enableCamera: true,
        selectedAssets: images,
        cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
        materialOptions: MaterialOptions(
          actionBarColor: "#abcdef",
          actionBarTitle: "Example App",
          allViewTitle: "All Photos",
          useDetailsView: false,
          selectCircleStrokeColor: "#000000",
        ),
      );
    } on Exception catch (e) {
      print(e);
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
    setState(() {
      images = resultList;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        heroTag: "btn1",
        backgroundColor: ColorHelper.orange,
        child: Icon(Icons.add_photo_alternate),
        onPressed: loadAssets,
      ),
      appBar: new AppBar(
        title: Text('បញ្ជីរូបភាព'),
        backgroundColor: ColorHelper.orange,
      ),
      body: Column(
        children: <Widget>[
          //Error message
          errorMessage != "" ? 
          Container(
            margin: EdgeInsets.only(left: 10, right: 10, top: 10),
            height: 50,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(4)),
              color: ColorHelper.red.withOpacity(0.5),
            ),
            child: Center(
              child: Text("$errorMessage", style: TextStyle(color: ColorHelper.swhite, fontSize: 15),),
            ),
          ):
          Container(),

          Expanded(
            child: Container(
              margin: EdgeInsets.only(left: 10, right: 10, top: 10),
              child: buildGridView(),
            ),
          ),
          SafeArea(
            child: Container(
              margin: EdgeInsets.all(10),
              decoration: BoxDecoration(
                color: ColorHelper.green,
                borderRadius: BorderRadius.all(Radius.circular(4))
              ),
              height: 50,
              child: InkWell(
                onTap: () {
                  if(images.length > 0) {
                    setState(() {
                      errorMessage = "";
                    });
                    // Call function upload multiple files
                    _uploadFiles();
                  } else {
                    setState(() {
                      errorMessage = "សូមបញ្ជូលរូបភាព";
                    });
                  } 
                },
                child: Center(
                  child: Text("រួចរាល់", style: TextStyle(color: ColorHelper.swhite, fontSize: 15, fontWeight: FontWeight.w500,),),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
6
sreng bona

lorsque vous choisissez des images de la galerie, appelées getFileList () puis appelées set state, utilisez d'abord la variable globale de la liste de fichiers et effacez à chaque fois cette liste lorsque vous sélectionnez à nouveau des images.

  List<File> listFile = List<File>();
  images = resultList;
  _error = error;
   getFileList();

 void getFileList() async{
  listFile.clear();
 for(int i=0; i<images.length; i++){
  var path= await images[i].filePath;
  print(path);
  var file=await getImageFileFromAssets(path);
  print(file);
  listFile.add(file);
}
 setState(() {

 });
}

getImageFileFromAsset est utilisé pour convertir l'actif en fichier

Future<File> getImageFileFromAsset(String path) async {
final file = File(path);
return file;

}

et utilisez listFile dans formdata.

1
Avinash

Voici comment obtenir une liste de tableaux d'octets à partir d'une liste de Assets:

List<Asset> images;
...

List<ByteData> byteDataList = await Future.wait(images.map((Asset image) => image.getByteData()));

List<Uint8List> byteArrayList = byteDataList.map((ByteData byteData) {
  ByteBuffer byteBuffer = byteData.buffer;
  return byteBuffer.asUint8List(byteData.offsetInBytes, byteBuffer.lengthInBytes);
}).toList();

Vous pouvez maintenant utiliser la liste des tableaux d'octets pour créer une charge utile à l'aide du client réseau de votre choix. Pour ceux qui n'utilisent pas de clients réseau tiers, ce serait un MultipartRequest avec plusieurs MultipartFile.fromBytes.

1
Ovidiu

Vous pouvez utiliser file_picker et obtenir la liste des fichiers sélectionnés directement. Il prend en charge la sélection multiple et fournit le chemin du fichier en réponse. Ce sera le moyen le plus simple.

List<File> files = await FilePicker.getMultiFilePath(
          type: FileType.IMAGE);
0
Vamsi Krishna

J'ai utilisé le plugin dio et multi_image dans mon application et cela fonctionne correctement. Ce que je fais, c'est donner mes extraits de code ici. Vous pouvez dire que c'est une version fonctionnelle et qu'elle devrait fonctionner dans n'importe quelle application.

classe de bloc

final imageController = BehaviorSubject<List<Asset>>();
StreamSink<List<Asset>> get sinkImages =>
  imageController.sink;
Stream<List<Asset>> get getImages => imageController.stream;

Future<void> loadImages(imageCount) async {
List<Asset> imageList = List<Asset>();
String error = 'No Error Dectected';

try {
  imageList = await MultiImagePicker.pickImages(
    maxImages: imageCount,
    enableCamera: true,
    cupertinoOptions: CupertinoOptions(
      takePhotoIcon: "chat",
    ),
    materialOptions: MaterialOptions(
      actionBarColor: "#0A73B1",
      statusBarColor: "#0A73B1",
      actionBarTitle: "Select Image",
      allViewTitle: "All Photos",
      useDetailsView: false,
      selectCircleStrokeColor: "#000000",
    ),
  );
} on Exception catch (e) {
  error = e.toString();
  print(error);
}

_error = error;
imageController.add(imageList);
}

// appelez cette méthode lorsque vous lancez un appel API

Future<GenericResponse> uploadImageRequest() async {
      RequestModel reqModel = RequestModel(
                     uploadImageList: getImages);

      final SharedPref prefs = SharedPref();
      String token = await prefs.readString(accessToken);

      GenericResponse response = await _application.repository
          .uploadRequest(reqModel: reqModel, accessToken: token);

      return response;
    }

Donc, vous avez déjà votre liste d'images par ceci. Et définissez également ces listes dans votre classe de modèle de demande. Maintenant, envoyons ces images en plusieurs parties en utilisant dio.

Méthode de classe API

// appel depuis la classe du référentiel

Future<GenericResponse> uploadRequest(
  {RequestModel reqModel, String accessToken}) async {
return await _apiProvider.uploadRequest(
    reqModel: reqModel, accessToken: accessToken);
}

// télécharger une demande d'API d'image

Future<ResponseModel> uploadRequest(
  {RequestModel requestModel, String accessToken}) async {

List<MultipartFile> imageList = [];

imageList = await getMultiPartImages(requestModel.imageList);

FormData formData = FormData.fromMap(RequestModel(
        uploadImageList: imageList,
    .toJson());

try {
  Response response = await getDio().post(
    'api/endpoint',
    options: Options(headers: {
      'Authorization': 'Bearer $accessToken',
    }),
    data: formData,
  );
  return ResponseModel.fromJson(response.data);
} catch (error, stacktrace) {
  debugPrint("Exception occured: $error stackTrace: $stacktrace");
  return ResponseModel.withError(handleError(error));
 }
}

// classe de modèle podo

class RequestModel {
 var uploadImageList;

 RequestModel(
  {this.uploadImageList});

 RequestModel.fromJson(Map<String, dynamic> json) {
  uploadImageList = json['image_list'];
 }

Map<String, dynamic> toJson() {
 final Map<String, dynamic> data = new Map<String, dynamic>();
 data['image_list'] = this.uploadImageList;
 return data;
}

@override
String toString() {
  return toJson().toString();
 }
}
0
demo_Ashif