我在一个有状态的小部件中包含了几个Future方法。相同的方法出现在应用程序的不同部分。我想将方法添加到一个类中,而不是在应用程序中重写四次,但我没能弄清楚,因为几个方法调用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),假设一个方法的建议解决方案可以应用于所有方法。如果我需要提供更多的代码,我将很乐意这样做。如有任何帮助,我将不胜感激。
当你使用第三方库在你的应用程序之外的东西,如挑选一张照片,下载一些数据,使HTTP调用。考虑为这些东西创建服务类,服务类基本上是这样的:具有单一职责的类,比如这个类,应该只做一件事。在你的例子中,你应该创建ImagePickerService类的工作是选择一个图像并返回给你,你不应该在其中调用任何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
});
}
现在当你创建一个新页面时,你只需要创建一个页面并在其中定义一些服务。
您可以从提取的方法中返回pickedFile
,然后每个使用结果的类可以使用返回值调用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();
}
}