flutter_image_picker/lib/src/ui/image_picker.dart

167 lines
5.7 KiB
Dart
Raw Normal View History

2022-11-01 08:24:41 +01:00
// SPDX-FileCopyrightText: 2022 Iconica
//
// SPDX-License-Identifier: BSD-3-Clause
2024-08-07 13:31:53 +02:00
import "package:flutter/material.dart";
2024-09-05 10:33:26 +02:00
import "package:flutter/services.dart";
2024-08-07 13:31:53 +02:00
import "package:flutter_image_picker/flutter_image_picker.dart";
import "package:image_picker/image_picker.dart";
2022-08-31 10:09:36 +02:00
2024-02-06 16:18:57 +01:00
/// The Image Picker class generates the Image Picker Widget which can be
/// displayed in your application. If you call the class you can give it 4
/// optional variables:
/// The first one is the [ImagePickerTheme] which can be used to change the UI
/// of the widget.
/// The second one is the [ImagePickerConfig] which can be used to configure the
/// behaviour of the image picker.
/// The third one is your own implementation of the ImagePickerService. Which
/// can be used in testing for example.
/// The fourth one is a custom Button widget.
2022-09-01 16:44:53 +02:00
class ImagePicker extends StatelessWidget {
const ImagePicker({
2024-02-22 16:22:22 +01:00
this.theme = const ImagePickerTheme(),
this.config = const ImagePickerConfig(),
this.service,
2024-09-05 10:33:26 +02:00
this.onError,
super.key,
});
2022-09-01 16:44:53 +02:00
2022-09-05 09:54:42 +02:00
/// ImagePickerTheme can be used to change the UI of the Image Picker Widget to change the text/icons to your liking.
2024-02-22 16:22:22 +01:00
final ImagePickerTheme theme;
2022-09-05 09:54:42 +02:00
2024-02-06 16:18:57 +01:00
/// ImagePickerConfig can be used to define the size and quality for the
/// uploaded image.
2024-02-22 16:22:22 +01:00
final ImagePickerConfig config;
2024-02-06 16:18:57 +01:00
/// The ImagePickerService can be used if you want to use your own
/// implementation of the Image Service if you want to use it for testing or
/// add more features. If null the current implementation will be used.
2024-02-22 16:22:22 +01:00
final ImagePickerService? service;
2022-08-31 10:09:36 +02:00
2024-09-05 10:33:26 +02:00
final Function(PlatformException error)? onError;
2022-09-01 16:44:53 +02:00
@override
2024-02-06 16:18:57 +01:00
Widget build(BuildContext context) => SingleChildScrollView(
child: Column(
children: <Widget>[
2024-08-07 13:31:53 +02:00
ListTile(
title: Text(
theme.title,
style:
theme.titleStyle ?? Theme.of(context).textTheme.titleMedium,
textAlign: theme.titleAlignment,
),
),
2024-02-06 16:18:57 +01:00
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
2023-04-03 14:44:42 +02:00
_generateIconButtonWithText(
context,
2024-02-22 16:22:22 +01:00
theme.selectImageIcon,
theme,
2024-02-06 16:18:57 +01:00
Icons.image,
ImageSource.gallery,
2024-02-22 16:22:22 +01:00
theme.selectImageText,
2024-09-05 10:33:26 +02:00
onError,
2023-04-03 14:44:42 +02:00
),
2024-02-22 16:22:22 +01:00
if (config.cameraOption ?? true) ...[
2024-02-06 16:18:57 +01:00
SizedBox(
2024-02-22 16:22:22 +01:00
width: theme.spaceBetweenIcons,
2024-02-06 16:18:57 +01:00
),
_generateIconButtonWithText(
context,
2024-02-22 16:22:22 +01:00
theme.makePhotoIcon,
theme,
2024-02-06 16:18:57 +01:00
Icons.camera_alt_rounded,
ImageSource.camera,
2024-02-22 16:22:22 +01:00
theme.makePhotoText,
2024-09-05 10:33:26 +02:00
onError,
2024-02-06 16:18:57 +01:00
),
],
],
),
2024-02-22 16:22:22 +01:00
if (theme.closeButtonBuilder != null) ...[
theme.closeButtonBuilder!.call(
() => Navigator.of(context).pop(),
),
] else ...[
const SizedBox(height: 30),
Center(
child: SizedBox(
width: 300,
height: 40,
2024-02-28 12:00:33 +01:00
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
),
onPressed: () => Navigator.of(context).pop(),
child: const Text(
2024-08-07 13:31:53 +02:00
"Close",
2024-02-28 12:00:33 +01:00
style: TextStyle(
fontSize: 15,
color: Colors.white,
),
2024-02-28 12:00:33 +01:00
),
),
2024-02-06 16:18:57 +01:00
),
2024-02-22 16:22:22 +01:00
),
const SizedBox(height: 30),
],
2024-02-06 16:18:57 +01:00
],
),
);
2022-08-31 12:31:54 +02:00
2024-02-07 09:53:11 +01:00
/// The [_generateIconButtonWithText] function returns a column that includes
2024-02-06 16:18:57 +01:00
/// an [IconButton] and [Text].
2024-02-07 09:53:11 +01:00
/// The function requires the following parameters to be able to generate an
2024-02-06 16:18:57 +01:00
/// icon with text:
2024-02-07 09:53:11 +01:00
/// [context] The build context that is required to make the [pickImage]
2024-02-06 16:18:57 +01:00
/// function in [_imagePickerService] work.
2024-02-07 09:53:11 +01:00
/// [imagePickerTheme] The ImagePickerTheme that includes all default values
2024-02-06 16:18:57 +01:00
/// for the Image Picker Dialog.
2024-02-07 09:53:11 +01:00
/// [icon] The icon that needs to be displayed, requires an [IconData] as
2024-02-06 16:18:57 +01:00
///value to be used.
2024-02-07 09:53:11 +01:00
/// [imageSource] The type of [ImageSource] to be used to pick an image when
2024-02-06 16:18:57 +01:00
/// pressed on the icon.
2022-09-01 10:22:32 +02:00
/// [bottomText] The text that's displayed underneath the icon.
Column _generateIconButtonWithText(
2024-02-06 16:18:57 +01:00
BuildContext context,
Widget? customIcon,
ImagePickerTheme imagePickerTheme,
IconData icon,
ImageSource imageSource,
String bottomText,
2024-09-05 10:33:26 +02:00
Function(PlatformException error)? onError,
2024-02-06 16:18:57 +01:00
) =>
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
InkWell(
key: Key(bottomText),
onTap: () async {
var navigator = Navigator.of(context);
2024-09-05 10:33:26 +02:00
Uint8List? image;
try {
image = await (service ?? ImagePickerServiceDefault())
.pickImage(imageSource, config: config);
} on PlatformException catch (e) {
debugPrint("image_picker_error: $e");
onError?.call(e);
}
2024-02-06 16:18:57 +01:00
navigator.pop(image);
},
child: customIcon ??
Icon(
icon,
size: imagePickerTheme.iconSize,
color: imagePickerTheme.iconColor,
),
),
2024-02-06 16:18:57 +01:00
Text(
bottomText,
2024-02-22 16:22:22 +01:00
style: theme.iconTextStyle,
2024-02-06 16:18:57 +01:00
),
],
);
2022-08-31 10:09:36 +02:00
}