I have a goal to make some "drop image area" on my chat app, similiar from Whatsapp, It's means that, when user drop some image on screen, i'll uploaded on a local file. However, it seems that FlutterFlow is slightlhy different from Flutter, and some flutter code it's not "Parsed" or "Process" in flutterflow, like the operator Imagebytes.
So anyone knows some logic to save an image from a dropzone, I did a code of it, and it worked, but i cound't save the imagebyte like a FFUploadedFile
import 'package:flutter_dropzone/flutter_dropzone.dart';
import 'dart:typed_data';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class FileDropScreen extends StatefulWidget {
const FileDropScreen({
Key? key,
this.width,
this.height,
this.ondrop,
}) : super(key: key);
final double? width;
final double? height;
final Future<dynamic> Function()? ondrop;
@override
_FileDropScreenState createState() => _FileDropScreenState();
}
class _FileDropScreenState extends State<FileDropScreen> {
late DropzoneViewController controller;
Uint8List? _imageBytes;
ValueNotifier<bool> isHovered = ValueNotifier(false);
Uint8List? get imageBytes => _imageBytes; // Getter público para _imageBytes
@override
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
height: widget.height,
child: Stack(
children: [
DropzoneView(
operation: DragOperation.copy,
cursor: CursorType.grab,
onHover: () {
isHovered.value = true;
},
onLeave: () {
isHovered.value = false;
},
onCreated: (ctrl) => controller = ctrl,
onLoaded: () => print('Zone loaded'),
onError: (ev) => print('Zone error: $ev'),
onDrop: (ev) async {
isHovered.value = false;
final data = await controller.getFileData(ev);
if (data != null) {
setState(() {
_imageBytes = data;
});
final file = await saveImageToFile(data);
print('Imagem salva em: ${file.path}');
}
// Chama a função ondrop assim que um arquivo é solto na Dropzone
if (widget.ondrop != null) {
await widget.ondrop!();
}
},
onDropInvalid: (ev) => print('Zone invalid MIME: $ev'),
onDropMultiple: (ev) async {
print('Zone drop multiple: $ev');
},
),
Positioned.fill(
child: ValueListenableBuilder<bool>(
valueListenable: isHovered,
builder: (context, isHovered, child) {
return AnimatedContainer(
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFBDBDBD)),
color: isHovered ? Color(0xFF80DEEA) : Colors.transparent,
),
child: Center(
child: Text(
isHovered ? 'Pode soltar :)' : 'Solte um arquivo aqui',
style: TextStyle(
color: isHovered ? Colors.white : Color(0xFFBDBDBD)),
),
),
);
},
),
),
if (_imageBytes != null) // Se houver imagem, exiba-a
Positioned.fill(
child: Image.memory(
_imageBytes!,
fit: BoxFit.contain,
),
),
],
),
);
}
Future<File> saveImageToFile(Uint8List imageBytes) async {
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/image.png';
final file = File(filePath);
await file.writeAsBytes(imageBytes);
return file;
}
}