1
- import 'dart:io' ;
2
1
import 'dart:typed_data' ;
3
-
2
+ import 'package:async/async.dart' ;
4
3
import 'package:flutter/foundation.dart' ;
5
4
import 'package:flutter/material.dart' ;
6
5
import 'package:flutter_form_builder/flutter_form_builder.dart' ;
@@ -52,12 +51,13 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
52
51
List <dynamic >? initialValue,
53
52
InputDecoration decoration = const InputDecoration (),
54
53
ValueChanged <List <dynamic >?>? onChanged,
55
- ValueTransformer <List <dynamic >>? valueTransformer,
54
+ ValueTransformer <List <dynamic >? >? valueTransformer,
56
55
bool enabled = true ,
57
56
FormFieldSetter <List <dynamic >>? onSaved,
58
57
AutovalidateMode autovalidateMode = AutovalidateMode .disabled,
59
58
VoidCallback ? onReset,
60
59
FocusNode ? focusNode,
60
+ WidgetBuilder ? loadingWidget,
61
61
this .previewWidth = 130 ,
62
62
this .previewHeight = 130 ,
63
63
this .previewMargin,
@@ -103,7 +103,7 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
103
103
children: [
104
104
if (field.value != null )
105
105
...field.value! .map <Widget >((dynamic item) {
106
- assert (item is File ||
106
+ assert (item is XFile ||
107
107
item is String ||
108
108
item is Uint8List );
109
109
return Stack (
@@ -117,8 +117,11 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
117
117
? Image .memory (item, fit: BoxFit .cover)
118
118
: item is String
119
119
? Image .network (item, fit: BoxFit .cover)
120
- : Image .file (item as File ,
121
- fit: BoxFit .cover),
120
+ : XFileImage (
121
+ file: item,
122
+ fit: BoxFit .cover,
123
+ loadingWidget: loadingWidget,
124
+ ),
122
125
),
123
126
if (state.enabled)
124
127
InkWell (
@@ -187,12 +190,6 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
187
190
< dynamic > [...? field.value, image]);
188
191
Navigator .pop (state.context);
189
192
},
190
- onImage: (image) {
191
- field.didChange (
192
- < dynamic > [...? field.value, image]);
193
- onChanged? .call (field.value);
194
- Navigator .pop (state.context);
195
- },
196
193
);
197
194
},
198
195
);
@@ -216,3 +213,38 @@ class _FormBuilderImagePickerState
216
213
value != null &&
217
214
value! .length >= widget.maxImages! ;
218
215
}
216
+
217
+ class XFileImage extends StatefulWidget {
218
+ const XFileImage ({
219
+ Key ? key,
220
+ required this .file,
221
+ this .fit,
222
+ this .loadingWidget,
223
+ }) : super (key: key);
224
+ final XFile file;
225
+ final BoxFit ? fit;
226
+ final WidgetBuilder ? loadingWidget;
227
+ @override
228
+ State <XFileImage > createState () => _XFileImageState ();
229
+ }
230
+
231
+ class _XFileImageState extends State <XFileImage > {
232
+ final _memoizer = AsyncMemoizer <Uint8List >();
233
+
234
+ @override
235
+ Widget build (BuildContext context) {
236
+ return FutureBuilder <Uint8List >(
237
+ future: _memoizer.runOnce (widget.file.readAsBytes),
238
+ builder: (context, snapshot) {
239
+ final data = snapshot.data;
240
+ if (data == null ) {
241
+ return widget.loadingWidget? .call (context) ??
242
+ Center (
243
+ child: CircularProgressIndicator (),
244
+ );
245
+ }
246
+ return Image .memory (data, fit: widget.fit);
247
+ },
248
+ );
249
+ }
250
+ }
0 commit comments