如何解决在 Flutter 中使用 imagePicker 和 Firebase Storage 时在哪里应用 setState 方法
首先提前谢谢大家。我觉得答案就在那里,只是我看不到。这是我想要实现的目标:
我想将 Image_Picker 选择的照片上传到 Firestore 并设置在屏幕上。
- 全局变量
String downloadURL = '';
File _image;
final picker = ImagePicker();
- 从图库中选择一张照片(效果很好)
Future getImage() async {
final pickedFile = await picker.getImage(
source: ImageSource.gallery,imageQuality: 75,);
_image = File(pickedFile.path);
uploadImage(_image);
}
- 将其上传到 Firestore Storage(工作正常)
Future<void> uploadImage(File imageFile) async {
try {
String imageLocation = 'images/${_auth.currentUser.uid}.jpg';
await _storage.ref(imageLocation).putFile(imageFile);
setState(() {}); ///////// This did not work
} on FirebaseException catch (e) {
print(e.code);
} catch (e) {
print(e.message);
}
}
- 从 Firebase 获取上传的照片(工作正常)
Future<void> downloadImageURL() async {
downloadURL = await _storage
.ref('images/${_auth.currentUser.uid}.jpg')
.getDownloadURL();
}
- 在我的小部件中
image: downloadURL == null || downloadURL.isEmpty
? NetworkImage(some Default Image)
: NetworkImage(downloadURL),
现在我知道我可以使用 Image_Picker 设置的“_image”文件,并通过 setState 更新应用程序,但这当然不是目标。 我的问题是我在哪里使用 setState 在屏幕上显示选择的照片?
解决方法
首先我给你链接了官方的flutter指南,方法setState
https://api.flutter.dev/flutter/widgets/State/setState.html
setState 方法不会重新加载应用程序.. 它会通知核心某个对象的状态已更改.. 如果您在页面中并调用 setState 方法,则只有该页面将被“重新加载”或. 更好地说.. 该页面的状态将被重新加载。
所以要回答您的问题,您必须在数据到位时调用 setState 方法。 当您调用 setState 方法时,将调用 build 方法,因此您的带有 url 图像的变量已在您的 build 方法中更新,您将拥有它
再见:D
,将 setState 放在哪里完全取决于您的应用流程以及您希望它何时发生。
但是假设您有一个页面或小部件,您想要显示 NetworkImage
。您可以在其他地方初始化 downloadUrl
并将其传递给小部件,然后在 initState 中设置 NetworkImage
。
class ImageWidget extends StatefulWidget {
final String downloadUrl;
const ImageWidget({Key key,this.downloadUrl}) : super(key: key);
@override
_ImageWidgetState createState() => _ImageWidgetState();
}
class _ImageWidgetState extends State<ImageWidget> {
NetworkImage networkImage;
@override
void initState() {
super.initState();
_setNetworkImage(widget.downloadUrl);
}
void _setNetworkImage(String url) {
setState(() {
if (url.isEmpty || url == null) {
networkImage = NetworkImage('some Default Image');
} else {
networkImage = NetworkImage(widget.downloadUrl);
}
});
}
@override
Widget build(BuildContext context) {
return ...display networkImage how you want it...
}
}
如果这对您的应用流程不起作用,请考虑具体说明您希望它发生的方式和时间,然后有人可以给您更好的答案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。