从 ListView 中的异步函数获取数据(没有 FutureBuilder)
Get data from async function inside ListView (without FutureBuilder)
我的应用程序主页使用 ListView.builder
创建 post 的提要。每个 post 都必须显示所有者的个人资料图片以及其他数据。在 ListView.builder
中,我调用一个函数从 Firebase 获取个人资料图片 URL
像这样:
ListView.builder(
itemCount: listPosts.length,
itemBuilder: (BuildContext context, int index) {
// We retrieve the post at index « index »
final post = listPosts[index];
// Get name from id
var parts = post.id.split('_');
var username = parts[0].trim();
// Get pfpUrl
String pfpUrlString = pfpUrl(username);
return _buildPost(
username, post.postUrlString, post.caption, pfpUrlString);
}),
我调用的 ```pfpUrl(username)''' 函数看起来像这样 returns URL 作为字符串:
pfpUrl(String username) async {
// Get pfpUrl
String pfpUrlString = await FirebaseStorage.instance
.ref()
.child("$username/profile_picture.png")
.getDownloadURL();
return pfpUrlString;
}
所以函数 returns String 但我不能在 ListView.builder
中使用 await
调用它,因为它不是异步函数。我不能使用 FutureBuilder
,因为用户名来自 post id,我只能在 ListView.Builder
中获取它。我没有返回值,而是尝试创建一个全局变量并将其设置为函数中的每个 URL,然后将该变量设置为构建器中的 URL。这不起作用,因为它最终会在每个 post 上放置随机的个人资料图片。有人可以给我解决方案吗?
你可以 return 一个 FutureBuilder 在那里你得到你的图像 Url 然后 return 在你的 _buildPost
这样试试:
ListView.builder(
itemCount: listPosts.length,
itemBuilder: (BuildContext context, int index) {
// We retrieve the post at index « index »
final post = listPosts[index];
// Get name from id
var parts = post.id.split('_');
var username = parts[0].trim();
// Get pfpUrl
String pfpUrlString = pfpUrl(username);
return FutureBuilder(
future: <your future to get the image Url>,
builder: (BuildContext context, AsyncSnapshot snapshot){
return _buildPost(
username, post.postUrlString, post.caption, pfpUrlString);
},
);
}),
您可以使用此小部件从用户名加载和显示个人资料照片。
在你的 _buildPost 方法中这样使用。:
ProfileImageWidget('username')
class ProfileImageWidget extends StatelessWidget {
final username;
ProfileImageWidget(this.username){
getUrl = FirebaseStorage.instance
.ref()
.child("$username/profile_picture.png")
.getDownloadURL();
}
late Future<String> getUrl;
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: getUrl,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if(!snapshot.hasData) return Text('getting profile url');
return Image.network(snapshot.data!);
});
}
}
我的应用程序主页使用 ListView.builder
创建 post 的提要。每个 post 都必须显示所有者的个人资料图片以及其他数据。在 ListView.builder
中,我调用一个函数从 Firebase 获取个人资料图片 URL
像这样:
ListView.builder(
itemCount: listPosts.length,
itemBuilder: (BuildContext context, int index) {
// We retrieve the post at index « index »
final post = listPosts[index];
// Get name from id
var parts = post.id.split('_');
var username = parts[0].trim();
// Get pfpUrl
String pfpUrlString = pfpUrl(username);
return _buildPost(
username, post.postUrlString, post.caption, pfpUrlString);
}),
我调用的 ```pfpUrl(username)''' 函数看起来像这样 returns URL 作为字符串:
pfpUrl(String username) async {
// Get pfpUrl
String pfpUrlString = await FirebaseStorage.instance
.ref()
.child("$username/profile_picture.png")
.getDownloadURL();
return pfpUrlString;
}
所以函数 returns String 但我不能在 ListView.builder
中使用 await
调用它,因为它不是异步函数。我不能使用 FutureBuilder
,因为用户名来自 post id,我只能在 ListView.Builder
中获取它。我没有返回值,而是尝试创建一个全局变量并将其设置为函数中的每个 URL,然后将该变量设置为构建器中的 URL。这不起作用,因为它最终会在每个 post 上放置随机的个人资料图片。有人可以给我解决方案吗?
你可以 return 一个 FutureBuilder 在那里你得到你的图像 Url 然后 return 在你的 _buildPost
这样试试:
ListView.builder(
itemCount: listPosts.length,
itemBuilder: (BuildContext context, int index) {
// We retrieve the post at index « index »
final post = listPosts[index];
// Get name from id
var parts = post.id.split('_');
var username = parts[0].trim();
// Get pfpUrl
String pfpUrlString = pfpUrl(username);
return FutureBuilder(
future: <your future to get the image Url>,
builder: (BuildContext context, AsyncSnapshot snapshot){
return _buildPost(
username, post.postUrlString, post.caption, pfpUrlString);
},
);
}),
您可以使用此小部件从用户名加载和显示个人资料照片。 在你的 _buildPost 方法中这样使用。:
ProfileImageWidget('username')
class ProfileImageWidget extends StatelessWidget {
final username;
ProfileImageWidget(this.username){
getUrl = FirebaseStorage.instance
.ref()
.child("$username/profile_picture.png")
.getDownloadURL();
}
late Future<String> getUrl;
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: getUrl,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if(!snapshot.hasData) return Text('getting profile url');
return Image.network(snapshot.data!);
});
}
}