Skip to content

Commit 32b3a59

Browse files
committed
improved the package to be cross platform, and pumped versions
1 parent 20a2767 commit 32b3a59

File tree

7 files changed

+117
-111
lines changed

7 files changed

+117
-111
lines changed

example/lib/main.dart

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,26 @@ class MyHomePage extends StatelessWidget {
4040
FormBuilderImagePicker(
4141
name: 'photos',
4242
decoration: const InputDecoration(labelText: 'Pick Photos'),
43-
maxImages: 1,
43+
maxImages: 3,
44+
initialValue: [
45+
'https://images.pexels.com/photos/7078045/pexels-photo-7078045.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
46+
],
4447
),
4548
const SizedBox(height: 15),
4649
ElevatedButton(
47-
child: Text('Submit'),
48-
onPressed: () {
49-
if (_formKey.currentState.saveAndValidate()) {
50-
print(_formKey.currentState.value);
51-
}
52-
})
50+
child: Text('Submit'),
51+
onPressed: () {
52+
if (_formKey.currentState.saveAndValidate()) {
53+
print(_formKey.currentState.value);
54+
}
55+
},
56+
),
57+
ElevatedButton(
58+
child: Text('Reset'),
59+
onPressed: () {
60+
_formKey.currentState?.reset();
61+
},
62+
)
5363
],
5464
),
5565
),

example/pubspec.lock

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,14 @@ packages:
77
name: archive
88
url: "https://pub.dartlang.org"
99
source: hosted
10-
version: "2.0.13"
11-
args:
12-
dependency: transitive
13-
description:
14-
name: args
15-
url: "https://pub.dartlang.org"
16-
source: hosted
17-
version: "1.6.0"
10+
version: "3.1.2"
1811
async:
1912
dependency: transitive
2013
description:
2114
name: async
2215
url: "https://pub.dartlang.org"
2316
source: hosted
24-
version: "2.5.0"
17+
version: "2.8.1"
2518
boolean_selector:
2619
dependency: transitive
2720
description:
@@ -42,7 +35,7 @@ packages:
4235
name: charcode
4336
url: "https://pub.dartlang.org"
4437
source: hosted
45-
version: "1.2.0"
38+
version: "1.3.1"
4639
clock:
4740
dependency: transitive
4841
description:
@@ -57,20 +50,20 @@ packages:
5750
url: "https://pub.dartlang.org"
5851
source: hosted
5952
version: "1.15.0"
60-
convert:
53+
cross_file:
6154
dependency: transitive
6255
description:
63-
name: convert
56+
name: cross_file
6457
url: "https://pub.dartlang.org"
6558
source: hosted
66-
version: "2.1.1"
59+
version: "0.3.1+5"
6760
crypto:
6861
dependency: transitive
6962
description:
7063
name: crypto
7164
url: "https://pub.dartlang.org"
7265
source: hosted
73-
version: "2.1.5"
66+
version: "3.0.1"
7467
fake_async:
7568
dependency: transitive
7669
description:
@@ -84,7 +77,7 @@ packages:
8477
name: file
8578
url: "https://pub.dartlang.org"
8679
source: hosted
87-
version: "6.0.0"
80+
version: "6.1.2"
8881
flutter:
8982
dependency: "direct main"
9083
description: flutter
@@ -96,17 +89,12 @@ packages:
9689
source: sdk
9790
version: "0.0.0"
9891
flutter_form_builder:
99-
dependency: "direct main"
92+
dependency: transitive
10093
description:
10194
name: flutter_form_builder
10295
url: "https://pub.dartlang.org"
10396
source: hosted
104-
version: "6.0.0-nullsafety.0"
105-
flutter_localizations:
106-
dependency: transitive
107-
description: flutter
108-
source: sdk
109-
version: "0.0.0"
97+
version: "7.0.0-beta.0"
11098
flutter_plugin_android_lifecycle:
11199
dependency: transitive
112100
description:
@@ -156,26 +144,26 @@ packages:
156144
name: image_picker
157145
url: "https://pub.dartlang.org"
158146
source: hosted
159-
version: "0.7.4"
147+
version: "0.8.4+2"
160148
image_picker_for_web:
161149
dependency: transitive
162150
description:
163151
name: image_picker_for_web
164152
url: "https://pub.dartlang.org"
165153
source: hosted
166-
version: "2.0.0"
154+
version: "2.1.3"
167155
image_picker_platform_interface:
168156
dependency: transitive
169157
description:
170158
name: image_picker_platform_interface
171159
url: "https://pub.dartlang.org"
172160
source: hosted
173-
version: "2.0.1"
161+
version: "2.4.1"
174162
integration_test:
175163
dependency: "direct dev"
176164
description: flutter
177165
source: sdk
178-
version: "0.9.2+2"
166+
version: "0.0.0"
179167
intl:
180168
dependency: transitive
181169
description:
@@ -203,7 +191,7 @@ packages:
203191
name: meta
204192
url: "https://pub.dartlang.org"
205193
source: hosted
206-
version: "1.3.0"
194+
version: "1.7.0"
207195
path:
208196
dependency: transitive
209197
description:
@@ -238,7 +226,7 @@ packages:
238226
name: process
239227
url: "https://pub.dartlang.org"
240228
source: hosted
241-
version: "4.0.0"
229+
version: "4.2.3"
242230
sky_engine:
243231
dependency: transitive
244232
description: flutter
@@ -250,7 +238,7 @@ packages:
250238
name: source_span
251239
url: "https://pub.dartlang.org"
252240
source: hosted
253-
version: "1.8.0"
241+
version: "1.8.1"
254242
stack_trace:
255243
dependency: transitive
256244
description:
@@ -278,7 +266,7 @@ packages:
278266
name: sync_http
279267
url: "https://pub.dartlang.org"
280268
source: hosted
281-
version: "0.2.0"
269+
version: "0.3.0"
282270
term_glyph:
283271
dependency: transitive
284272
description:
@@ -292,7 +280,7 @@ packages:
292280
name: test_api
293281
url: "https://pub.dartlang.org"
294282
source: hosted
295-
version: "0.2.19"
283+
version: "0.4.2"
296284
typed_data:
297285
dependency: transitive
298286
description:
@@ -313,14 +301,14 @@ packages:
313301
name: vm_service
314302
url: "https://pub.dartlang.org"
315303
source: hosted
316-
version: "5.5.0"
304+
version: "7.1.1"
317305
webdriver:
318306
dependency: transitive
319307
description:
320308
name: webdriver
321309
url: "https://pub.dartlang.org"
322310
source: hosted
323-
version: "2.1.2"
311+
version: "3.0.0"
324312
sdks:
325-
dart: ">=2.12.0 <3.0.0"
326-
flutter: ">=1.20.0"
313+
dart: ">=2.14.0 <3.0.0"
314+
flutter: ">=2.5.0"

example/pubspec.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ environment:
99

1010
dependencies:
1111
flutter:
12-
sdk: flutter
13-
flutter_form_builder: ^6.0.0-nullsafety.0
12+
sdk: flutter
1413
form_builder_image_picker:
1514
path: ../
1615

lib/src/form_builder_image_picker.dart

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import 'dart:io';
21
import 'dart:typed_data';
3-
2+
import 'package:async/async.dart';
43
import 'package:flutter/foundation.dart';
54
import 'package:flutter/material.dart';
65
import 'package:flutter_form_builder/flutter_form_builder.dart';
@@ -52,12 +51,13 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
5251
List<dynamic>? initialValue,
5352
InputDecoration decoration = const InputDecoration(),
5453
ValueChanged<List<dynamic>?>? onChanged,
55-
ValueTransformer<List<dynamic>>? valueTransformer,
54+
ValueTransformer<List<dynamic>?>? valueTransformer,
5655
bool enabled = true,
5756
FormFieldSetter<List<dynamic>>? onSaved,
5857
AutovalidateMode autovalidateMode = AutovalidateMode.disabled,
5958
VoidCallback? onReset,
6059
FocusNode? focusNode,
60+
WidgetBuilder? loadingWidget,
6161
this.previewWidth = 130,
6262
this.previewHeight = 130,
6363
this.previewMargin,
@@ -103,7 +103,7 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
103103
children: [
104104
if (field.value != null)
105105
...field.value!.map<Widget>((dynamic item) {
106-
assert(item is File ||
106+
assert(item is XFile ||
107107
item is String ||
108108
item is Uint8List);
109109
return Stack(
@@ -117,8 +117,11 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
117117
? Image.memory(item, fit: BoxFit.cover)
118118
: item is String
119119
? 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+
),
122125
),
123126
if (state.enabled)
124127
InkWell(
@@ -187,12 +190,6 @@ class FormBuilderImagePicker extends FormBuilderField<List<dynamic>> {
187190
<dynamic>[...?field.value, image]);
188191
Navigator.pop(state.context);
189192
},
190-
onImage: (image) {
191-
field.didChange(
192-
<dynamic>[...?field.value, image]);
193-
onChanged?.call(field.value);
194-
Navigator.pop(state.context);
195-
},
196193
);
197194
},
198195
);
@@ -216,3 +213,38 @@ class _FormBuilderImagePickerState
216213
value != null &&
217214
value!.length >= widget.maxImages!;
218215
}
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+
}

lib/src/image_source_sheet.dart

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import 'dart:io';
2-
import 'dart:typed_data' show Uint8List;
3-
41
import 'package:flutter/foundation.dart';
52
import 'package:flutter/material.dart';
63
import 'package:image_picker/image_picker.dart';
@@ -24,15 +21,7 @@ class ImageSourceBottomSheet extends StatefulWidget {
2421
final CameraDevice preferredCameraDevice;
2522

2623
/// Callback when an image is selected.
27-
///
28-
/// **Note**: This will work on web platform whereas [onImageSelected] will not.
29-
final void Function(Uint8List)? onImage;
30-
31-
/// Callback when an image is selected.
32-
///
33-
/// **Warning**: This will _NOT_ work on web platform because [File] is not
34-
/// available.
35-
final void Function(File)? onImageSelected;
24+
final void Function(XFile)? onImageSelected;
3625

3726
final Widget? cameraIcon;
3827
final Widget? galleryIcon;
@@ -46,14 +35,13 @@ class ImageSourceBottomSheet extends StatefulWidget {
4635
this.maxWidth,
4736
this.imageQuality,
4837
this.preferredCameraDevice = CameraDevice.rear,
49-
this.onImage,
5038
this.onImageSelected,
5139
this.cameraIcon,
5240
this.galleryIcon,
5341
this.cameraLabel,
5442
this.galleryLabel,
5543
this.bottomSheetPadding,
56-
}) : assert(null != onImage || null != onImageSelected),
44+
}) : assert(null != onImageSelected),
5745
super(key: key);
5846

5947
@override
@@ -67,28 +55,16 @@ class _ImageSourceBottomSheetState extends State<ImageSourceBottomSheet> {
6755
if (_isPickingImage) return;
6856
_isPickingImage = true;
6957
final imagePicker = ImagePicker();
70-
final pickedFile = await imagePicker.getImage(
58+
final pickedFile = await imagePicker.pickImage(
7159
source: source,
7260
maxHeight: widget.maxHeight,
7361
maxWidth: widget.maxWidth,
7462
imageQuality: widget.imageQuality,
7563
preferredCameraDevice: widget.preferredCameraDevice,
7664
);
7765
_isPickingImage = false;
78-
if (null != pickedFile) {
79-
if (kIsWeb) {
80-
if (null != widget.onImage) {
81-
widget.onImage!(await pickedFile.readAsBytes());
82-
}
83-
} else {
84-
if (null != widget.onImageSelected) {
85-
// Warning: this will not work on the web platform because pickedFile
86-
// will instead point to a network resource.
87-
final imageFile = File(pickedFile.path);
88-
// assert(null != imageFile);
89-
widget.onImageSelected!(imageFile);
90-
}
91-
}
66+
if (pickedFile != null) {
67+
widget.onImageSelected?.call(pickedFile);
9268
}
9369
}
9470

0 commit comments

Comments
 (0)