如何将 Future 方法从有状态小部件移动到它们自己的 class Flutter
How to move Future methods from Stateful widget to their own class Flutter
我有几个 Future 方法包含在有状态小部件中。相同的方法出现在应用程序的不同部分。我想将这些方法添加到一个 Class 而不是在应用程序中重写四次,但我一直无法弄清楚,因为有几个方法调用 setState 来更新 UI。当用户从他们的图库中选择图像、选择拍照、将所选图像上传到数据库以在应用程序中显示、压缩图像等时调用这些方法。
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
setState(() {
file = File(pickedFile!.path);
});
}
@override
Widget build(BuildContext context) {
return Container();
}
}
我只包含其中一种方法 (captureImageWithCamera),假设针对其中一种方法的建议解决方案可以应用于所有方法。如果我需要提供更多代码,我会很乐意这样做。任何帮助将不胜感激。
您可以从提取的方法中 return pickedFile
,然后每个使用结果的 class 都可以使用 returned 值调用 setState 本身。
class ImageCapturer {
Future<XFile?> captureImageWithCamera() async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
return pickedFile;
}
}
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
final file = await ImageCapturer().captureImageWithCamera();
setState(() {
this.file = File(file!.path);;
});
}
@override
Widget build(BuildContext context) {
return Container();
}
}
您可以使用回调参数将代码抽象为一个函数,如下所示:
class OtherExampleClass {
Future<void> captureImageWithCamera(
void Function(XFile? pickedFile) callback,
) async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
callback(pickedFile);
}
}
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
await OtherExampleClass().captureImageWithCamera((XFile? pickedFile) {
setState(() {
file = File(pickedFile!.path);
});
}
);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
当您将第三方库用于应用程序外部的某些内容时,例如选择照片、下载一些数据、进行 http 调用。
考虑为这些东西创建服务 class,服务 class 基本上是这样的:
a class 具有单一职责,像这样 class 应该只做一件事。
在您的情况下,您应该创建 ImagePickerService class 工作是选择一个图像,return 仅此而已,您不应该在其中调用任何 flutter 框架
喜欢 setState 因为更新 UI.
不是他的工作
class ImagePickerService {
//make this class singleton so you do not make a new instance every time you want it.
static final ImagePickerService _instance = ImagePickerService._();
ImagePickerService._();
factory ImagePickerService() => _instance;
Future<XFile?> pickImage(ImageSource imageSource) async {
return await ImagePicker().pickImage(
source: imageSource,
);
}
}
所以现在当你想要选择一个图像时,你只需要像这样调用这个服务。
onTap: () async {
final file = await ImagePickerService().pickImage(ImageSource.camera);
setState(() {
// you got the file boss do anything you want
});
}
现在,当您创建新页面时,您只需创建页面并在其中定义一些服务。
我有几个 Future 方法包含在有状态小部件中。相同的方法出现在应用程序的不同部分。我想将这些方法添加到一个 Class 而不是在应用程序中重写四次,但我一直无法弄清楚,因为有几个方法调用 setState 来更新 UI。当用户从他们的图库中选择图像、选择拍照、将所选图像上传到数据库以在应用程序中显示、压缩图像等时调用这些方法。
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
setState(() {
file = File(pickedFile!.path);
});
}
@override
Widget build(BuildContext context) {
return Container();
}
}
我只包含其中一种方法 (captureImageWithCamera),假设针对其中一种方法的建议解决方案可以应用于所有方法。如果我需要提供更多代码,我会很乐意这样做。任何帮助将不胜感激。
您可以从提取的方法中 return pickedFile
,然后每个使用结果的 class 都可以使用 returned 值调用 setState 本身。
class ImageCapturer {
Future<XFile?> captureImageWithCamera() async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
return pickedFile;
}
}
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
final file = await ImageCapturer().captureImageWithCamera();
setState(() {
this.file = File(file!.path);;
});
}
@override
Widget build(BuildContext context) {
return Container();
}
}
您可以使用回调参数将代码抽象为一个函数,如下所示:
class OtherExampleClass {
Future<void> captureImageWithCamera(
void Function(XFile? pickedFile) callback,
) async {
Get.back();
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.camera,
);
callback(pickedFile);
}
}
class ExampleClass extends StatefulWidget {
const ExampleClass({Key? key}) : super(key: key);
@override
State<ExampleClass> createState() => _ExampleClassState();
}
class _ExampleClassState extends State<ExampleClass> {
File? file;
Future<void> _captureImageWithCamera() async {
await OtherExampleClass().captureImageWithCamera((XFile? pickedFile) {
setState(() {
file = File(pickedFile!.path);
});
}
);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
当您将第三方库用于应用程序外部的某些内容时,例如选择照片、下载一些数据、进行 http 调用。 考虑为这些东西创建服务 class,服务 class 基本上是这样的: a class 具有单一职责,像这样 class 应该只做一件事。 在您的情况下,您应该创建 ImagePickerService class 工作是选择一个图像,return 仅此而已,您不应该在其中调用任何 flutter 框架 喜欢 setState 因为更新 UI.
不是他的工作class ImagePickerService {
//make this class singleton so you do not make a new instance every time you want it.
static final ImagePickerService _instance = ImagePickerService._();
ImagePickerService._();
factory ImagePickerService() => _instance;
Future<XFile?> pickImage(ImageSource imageSource) async {
return await ImagePicker().pickImage(
source: imageSource,
);
}
}
所以现在当你想要选择一个图像时,你只需要像这样调用这个服务。
onTap: () async {
final file = await ImagePickerService().pickImage(ImageSource.camera);
setState(() {
// you got the file boss do anything you want
});
}
现在,当您创建新页面时,您只需创建页面并在其中定义一些服务。