Upload image in flutter web

前端 未结 3 653
别跟我提以往
别跟我提以往 2021-01-03 16:37

Flutter web is still in technical preview but i want to pick an image from the disk and upload it to the server. Is there anyway to add HTML, JS to my flutter web project a

相关标签:
3条回答
  • 2021-01-03 16:59

    You can use image_picker_web :

    dependencies:
      image_picker_web: ^1.0.9
    

    picks Images (as Widget, File or Uint8List) and Videos (as File or Uint8List)

    0 讨论(0)
  • 2021-01-03 17:04

    You need addEventListener and also need to append it for woking it on mobile safari. I answered here too.

    Future<void> _setImage() async {
        final completer = Completer<List<String>>();
        InputElement uploadInput = FileUploadInputElement();
        uploadInput.multiple = true;
        uploadInput.accept = 'image/*';
        uploadInput.click();
        // onChange doesn't work on mobile safari
        uploadInput.addEventListener('change', (e) async {
            // read file content as dataURL
            final files = uploadInput.files;
            Iterable<Future<String>> resultsFutures = files.map((file) {
                final reader = FileReader();
                reader.readAsDataUrl(file);
                reader.onError.listen((error) => completer.completeError(error));
                return reader.onLoad.first.then((_) => reader.result as String);
            });
    
            final results = await Future.wait(resultsFutures);
            completer.complete(results);
        });
        // need to append on mobile safari
        document.body.append(uploadInput);
        final List<String> images = await completer.future;
        setState(() {
            _uploadedImages = images;
        });
        uploadInput.remove();
    }
    

    This also works:

    Future<void> _setImage() async {   
        final completer = Completer<List<String>>();
        final InputElement input = document.createElement('input');
        input
          ..type = 'file'
          ..multiple = true
          ..accept = 'image/*';
        input.click();
        // onChange doesn't work on mobile safari
        input.addEventListener('change', (e) async {
          final List<File> files = input.files;
          Iterable<Future<String>> resultsFutures = files.map((file) {
            final reader = FileReader();
            reader.readAsDataUrl(file);
            reader.onError.listen((error) => completer.completeError(error));
            return reader.onLoad.first.then((_) => reader.result as String);
          });
          final results = await Future.wait(resultsFutures);
          completer.complete(results);
        });
        // need to append on mobile safari
        document.body.append(input);
        // input.click(); can be here
        final List<String> images = await completer.future;
        setState(() {
          _uploadedImages = images;
        });
        input.remove();
    }
    
    0 讨论(0)
  • 2021-01-03 17:22

    This will do what you want for web. Just call it from any button and it will open the system dialog to chose the file.

    import 'dart:typed_data';
    import 'package:universal_html/prefer_sdk/html.dart';    
    import '../../../providers/form_provider.dart';
    
    Uint8List uploadedImage;
    
    startFilePickerWeb(ProviderForm formProvider) async {    
      InputElement uploadInput = FileUploadInputElement();
      uploadInput.click();
    
      uploadInput.onChange.listen((e) {
        // read file content as dataURL
        final files = uploadInput.files;
        if (files.length == 1) {
          final file = files[0];
          FileReader reader = FileReader();
    
          reader.onLoadEnd.listen((e) {
          //Here I send the imatge to my Provider 
            formProvider.setLogoEmpresa(reader.result);
          });
    
          reader.onError.listen((fileEvent) {
            print("Some Error occured while reading the file");
          });
    
          reader.readAsArrayBuffer(file);
        }
      });
    }
    

    The provider:

    class ProviderForm extends ChangeNotifier {
        Uint8List logoEmpresa;
        void setLogoEmpresa(Uint8List newFile) {
           logoEmpresa = newFile;
           notifyListeners();
        }
    }
    

    Then in your view you can render it like this, in case no imatge it show a attachement icon:

    Container(
          width: formProvider.logoEmpresa == null
              ? 70.0
              : 90.0,
          child: formProvider.logoEmpresa == null
              ? Icon(
                  Icons.attach_file,
                  size: 70.0,
                  color: kColorPrincipal,
                )
              : Image.memory(formProvider.logoEmpresa,
                  fit: BoxFit.fitWidth),
        ),
    

    If you have any question, please ask and I'll do my best to help.

    0 讨论(0)
提交回复
热议问题