2022-11-01 08:24:41 +01:00
|
|
|
// SPDX-FileCopyrightText: 2022 Iconica
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
2022-08-31 10:09:36 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2022-11-07 14:03:20 +01:00
|
|
|
import 'package:flutter_image_picker/flutter_image_picker.dart';
|
2022-08-31 10:09:36 +02:00
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
|
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.
|
2022-11-07 14:03:20 +01:00
|
|
|
/// The fourth one is a custom Button widget.
|
2022-09-01 16:44:53 +02:00
|
|
|
class ImagePicker extends StatelessWidget {
|
2022-11-07 14:03:20 +01:00
|
|
|
const ImagePicker({
|
|
|
|
this.imagePickerTheme = const ImagePickerTheme(),
|
|
|
|
this.imagePickerConfig = const ImagePickerConfig(),
|
|
|
|
this.imagePickerService,
|
|
|
|
this.customButton,
|
2022-10-21 16:21:06 +02:00
|
|
|
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.
|
2022-09-01 16:44:53 +02:00
|
|
|
final ImagePickerTheme imagePickerTheme;
|
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.
|
2022-11-07 14:03:20 +01:00
|
|
|
final ImagePickerConfig imagePickerConfig;
|
|
|
|
|
2022-09-08 14:23:46 +02:00
|
|
|
/// The Image Picker Dialog can have a custom button if you want to.
|
2022-09-30 09:27:02 +02:00
|
|
|
final Widget? customButton;
|
2022-09-08 14:23:46 +02:00
|
|
|
|
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.
|
2022-09-02 16:14:24 +02:00
|
|
|
final ImagePickerService? imagePickerService;
|
2022-08-31 10:09:36 +02:00
|
|
|
|
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>[
|
|
|
|
ListTile(
|
|
|
|
tileColor: imagePickerTheme.titleBackgroundColor,
|
|
|
|
title: Text(
|
|
|
|
textAlign: imagePickerTheme.titleAlignment,
|
|
|
|
imagePickerTheme.title,
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: imagePickerTheme.font,
|
|
|
|
fontSize: imagePickerTheme.titleTextSize,
|
|
|
|
color: imagePickerTheme.titleColor,
|
|
|
|
),
|
2022-11-07 14:03:20 +01:00
|
|
|
),
|
2022-08-31 14:42:17 +02:00
|
|
|
),
|
2024-02-06 16:18:57 +01:00
|
|
|
const SizedBox(height: 20),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
2023-04-03 14:44:42 +02:00
|
|
|
_generateIconButtonWithText(
|
|
|
|
context,
|
2024-02-06 16:18:57 +01:00
|
|
|
imagePickerTheme.selectImageIcon,
|
2023-04-03 14:44:42 +02:00
|
|
|
imagePickerTheme,
|
2024-02-06 16:18:57 +01:00
|
|
|
Icons.image,
|
|
|
|
ImageSource.gallery,
|
|
|
|
imagePickerTheme.selectImageText,
|
2023-04-03 14:44:42 +02:00
|
|
|
),
|
2024-02-06 16:18:57 +01:00
|
|
|
if (imagePickerConfig.cameraOption ?? true) ...[
|
|
|
|
SizedBox(
|
|
|
|
width: imagePickerTheme.spaceBetweenIcons,
|
|
|
|
),
|
|
|
|
_generateIconButtonWithText(
|
|
|
|
context,
|
|
|
|
imagePickerTheme.makePhotoIcon,
|
|
|
|
imagePickerTheme,
|
|
|
|
Icons.camera_alt_rounded,
|
|
|
|
ImageSource.camera,
|
|
|
|
imagePickerTheme.makePhotoText,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
),
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
SizedBox(
|
|
|
|
width: imagePickerTheme.closeButtonWidth,
|
|
|
|
height: imagePickerTheme.closeButtonHeight,
|
|
|
|
child: customButton ??
|
|
|
|
ElevatedButton(
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
backgroundColor:
|
|
|
|
imagePickerTheme.closeButtonBackgroundColor,
|
|
|
|
),
|
|
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
|
|
child: Text(
|
|
|
|
imagePickerTheme.closeButtonText,
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: imagePickerTheme.font,
|
|
|
|
fontSize: imagePickerTheme.closeButtonTextSize,
|
|
|
|
color: imagePickerTheme.closeButtonTextColor,
|
|
|
|
),
|
2022-11-07 14:03:20 +01:00
|
|
|
),
|
|
|
|
),
|
2024-02-06 16:18:57 +01:00
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
const SizedBox(height: 30),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
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,
|
|
|
|
) =>
|
|
|
|
Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
InkWell(
|
|
|
|
key: Key(bottomText),
|
|
|
|
onTap: () async {
|
|
|
|
var navigator = Navigator.of(context);
|
|
|
|
var image =
|
|
|
|
await (imagePickerService ?? ImagePickerServiceDefault())
|
|
|
|
.pickImage(imageSource, config: imagePickerConfig);
|
|
|
|
navigator.pop(image);
|
|
|
|
},
|
|
|
|
child: customIcon ??
|
|
|
|
Icon(
|
|
|
|
icon,
|
|
|
|
size: imagePickerTheme.iconSize,
|
|
|
|
color: imagePickerTheme.iconColor,
|
|
|
|
),
|
2022-11-07 14:03:20 +01:00
|
|
|
),
|
2024-02-06 16:18:57 +01:00
|
|
|
Text(
|
|
|
|
bottomText,
|
|
|
|
style: TextStyle(
|
|
|
|
fontFamily: imagePickerTheme.font,
|
|
|
|
fontSize: imagePickerTheme.iconTextSize,
|
|
|
|
color: imagePickerTheme.textColor,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
const SizedBox(height: 20),
|
|
|
|
],
|
|
|
|
);
|
2022-08-31 10:09:36 +02:00
|
|
|
}
|