Vous recherchez un sélecteur d'images sur le nouveau flutter web 1.9. J'ai trouvé un moyen, mais pour moins de 1,9, maintenant qui est fusionné, je ne sais pas comment puis-je y parvenir. Essayé avec dart: html mais ne fonctionne pas à la sortie! Seulement en courant
3 Réponses :
Il semble que pour Flutter web 1.10 dev
, le package universal_html est un bon candidat pour le poste temporairement vacant de dart:html
:
import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:universal_html/prefer_universal/html.dart' as html; class ImagePickerLabPage extends StatefulWidget { @override _ImagePickerLabPageState createState() => _ImagePickerLabPageState(); } class _ImagePickerLabPageState extends State<ImagePickerLabPage> { String name = ''; String error; Uint8List data; pickImage() { final html.InputElement input = html.document.createElement('input'); input ..type = 'file' ..accept = 'image/*'; input.onChange.listen((e) { if (input.files.isEmpty) return; final reader = html.FileReader(); reader.readAsDataUrl(input.files[0]); reader.onError.listen((err) => setState(() { error = err.toString(); })); reader.onLoad.first.then((res) { final encoded = reader.result as String; // remove data:image/*;base64 preambule final stripped = encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), ''); setState(() { name = input.files[0].name; data = base64.decode(stripped); error = null; }); }); }); input.click(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(name), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.open_in_browser), onPressed: () { pickImage(); }, ), body: Center( child: error != null ? Text(error) : data != null ? Image.memory(data) : Text('No data...'), ), ); } }
Merci, cela fonctionne bien, mais comment pouvons-nous garder son type comme image? Je veux juste le télécharger sur Firebase, mais ce n'est pas en tant qu'image.
html.InputReader et html.FileReader ne sont pas importés avec succès, indiquant une erreur. Pouvez-vous s'il vous plaît nous dire comment le résoudre?
@Umair Assurez-vous que vous avez spécifié le bon package dans pubspec.yaml
, et qu'aucun autre package de votre code n'a été importé avec html
-alias.
Message du compilateur: lib / main.dart: 240: 5: Erreur: Factory redirige vers la classe 'FileReader', qui est abstraite et ne peut pas être instanciée. Échec de la cible kernel_snapshot: exception: erreurs lors de la création de l'instantané: la génération nulle a échoué.
@Umair Vous pouvez créer une nouvelle question. Montrez-lui votre pubspec.yaml
et le code du fichier lib/main.dart
La solution qui a fonctionné pour moi est d'avoir changé ma chaîne et de m'assurer de n'utiliser que ce package dans ce code. Merci pour vos solutions
En fait, onChange ne fonctionne pas bien sur les safaris mobiles, il doit changer addEventListener et également l'ajouter.
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(); }
Cela fonctionne également:
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(); }
Merci Bulkin, ça aide vraiment !!
@Bulkin Merci! m'a sauvé comme image_picker_web a des conflits avec iOS (pour l'appareil que j'utilise image_picker) et mon application fonctionne à la fois sur le Web et sur l'appareil.
Holy Moly. tu es mon héros. Comment diable avez-vous compris cela? J'ai pensé que sur le Web mobile, le code flottant était en quelque sorte en arrière-plan lors de la sélection de fichiers ... mais j'étais totalement perdu sur ce qu'il fallait changer. J'ai besoin de comprendre votre document.
pourquoi n'utilisez-vous pas simplement: https://pub.dev/packages/image_picker_web
Il prend également en charge plusieurs types de sortie (fichier, widget, Uint8List)