Flutter 错误:无法将参数类型“List<Future<Widget>>”分配给参数类型“List<Widget>”
Posted
技术标签:
【中文标题】Flutter 错误:无法将参数类型“List<Future<Widget>>”分配给参数类型“List<Widget>”【英文标题】:Flutter error : The argument type 'List<Future<Widget>>' can't be assigned to the parameter type 'List<Widget>' 【发布时间】:2021-06-04 04:10:50 【问题描述】:我正在尝试从 Firebase Firestore 列出项目(已完成),并为每个项目从 Firebase Cloud Storage 获取不同的图像 URL。
我使用一个名为 getPhotoUrl 的函数来更改变量 photoUrl 的值。问题是 return 在 getPhotoUrl 之前执行。如果我在函数 getPhotoUrl 之前添加 await 并在 _docs.map((document) 之后添加 async,我收到一个错误,提示 参数类型“List
我的代码:
class PhotosList extends StatefulWidget
@override
_PhotosListState createState() => _PhotosListState();
class _PhotosListState extends State<PhotosList>
String photoUrl = 'lib/assets/default-image.png';
List<DocumentSnapshot> _docs;
getPhotoUrl(documentID)
Reference ref = storage
.ref('Users')
.child(currentUser.uid)
.child('Photos')
.child(documentID)
.child('image_1.jpg');
ref.getDownloadURL().then((value)
setState(()
photoUrl = value.toString();
);
).catchError((e)
setState(()
print(e.error);
);
);
@override
Widget build(BuildContext context)
return StreamBuilder(
stream: firestore
.collection('Users')
.doc(currentUser.uid)
.collection('Photos')
.orderBy('date')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
if (!snapshot.hasData) return CircularProgressIndicator();
_docs = snapshot.data.docs;
if (_docs.isEmpty)
return Center(
child: Text("The list is empty."));
return Container(
child: ResponsiveGridList(
desiredItemWidth: 100,
squareCells: true,
minSpacing: 5,
children: _docs.map((document)
getPhotoUrl(document.id);
return PhotosListItem(photoUrl: photoUrl);
).toList(),
),
);
,
);
【问题讨论】:
【参考方案1】:我认为你混合了两种不同的方式。在每个构建循环中,您映射您的文档并请求该 photoUrl,但在该方法中您调用 setState,它会重新触发您的构建方法。这样你应该在获取照片 url 和构建你的小部件的无限循环中结束。
您有三个选择:
-
加载您的 photoUrls 并将它们存储在您的小部件中 -> 调用 set state -> 检查您的映射函数是否已加载您的照片,如果是,请获取,如果不是,请调用您的 getPhotoUrl 函数
同步加载您的 photoUrls 并从您的函数返回 url 并将其设置为您的 PhotosListItem
(我更喜欢这个)将您的 documentId 添加到您的映射函数中的 photosListItem 中,并在您的项目中加载此照片 url。在此 PhotoListItem 中,您的 imageUrl 有一个变量,在 initState 中您调用 getPhotoUrl 函数
在您的 PhotoItem 内:
String imageUrl;
@override
void initState()
Future.delayed(Duration.zero, ()
setState(()
// load your data and set it to your variable
imageUrl = ..
);
);
super.initState();
【讨论】:
【参考方案2】:您可能会使用 FutureBuilder,因为 StreamBuilder 似乎是同步的:
How to convert Future<List> to List in flutter?
【讨论】:
【参考方案3】:感谢各位的回答,其实我找到了另一种解决方案,即在将图像上传到存储后直接在 Firestore 中获取和写入 URL。
这篇文章对我帮助很大:https://medium.com/swlh/uploading-images-to-cloud-storage-using-flutter-130ac41741b2
(PS:自这篇文章以来,一些 Firebase 名称发生了变化,但它仍然很有帮助。)
问候。
【讨论】:
以上是关于Flutter 错误:无法将参数类型“List<Future<Widget>>”分配给参数类型“List<Widget>”的主要内容,如果未能解决你的问题,请参考以下文章
Flutter中的参数类型“String”无法分配给参数类型“Uri”[重复]
Flutter SQLlite 参数类型“Future<String>”无法分配给参数类型“String”错误
错误:无法将参数类型“MaterialAccentColor”分配给参数类型“MaterialColor”
flutter error:参数类型'Future '无法分配给参数类型'小部件'