根据闭包上下文的要求,返回类型“Future<Image>”不是“Widget”

Posted

技术标签:

【中文标题】根据闭包上下文的要求,返回类型“Future<Image>”不是“Widget”【英文标题】:The return type 'Future<Image>' isn't a 'Widget', as required by the closure's context 【发布时间】:2020-10-14 03:48:45 【问题描述】:

我正在向 api 发送登录信息并获得一个图像 ID 号,我将其发送回 api 以获取图像,我想在网格中显示图像,但我得到一个“返回类型”根据闭包上下文的要求,Future' 不是一个 'Widget'。”错误。

recentAlbumArt 函数出现错误

import 'package:flutter/material.dart';
import 'package:test_music_app/API/api_call.dart';

import 'package:test_music_app/API/auth.dart';

class RecentlyAddedAlbums extends StatefulWidget 
  @override
  _RecentlyAddedAlbumsState createState() => _RecentlyAddedAlbumsState();


class _RecentlyAddedAlbumsState extends State<RecentlyAddedAlbums> 
  Future<List<Album>> albums;
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Container(
        child: FutureBuilder(
            future: fetchRecentlyAddedAlbums(),
            builder: (context, AsyncSnapshot<List<Album>> data) 
              switch (data.connectionState) 
                case ConnectionState.none:
                  return Text(
                    "none",
                    style: TextStyle(color: Colors.black),
                  );
                case ConnectionState.waiting:
                  return Center(
                      child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
                  ));
                case ConnectionState.active:
                  return Text('');
                case ConnectionState.done:
                  if (data.hasData) 
                    List<Album> albums = data.data;
                    return ListView.builder(
                      itemCount: albums.length,
                      itemBuilder: (context, index) 
                        return FutureBuilder(
                            future: recentAlbumArt(albums[index].coverArt),
                            builder: (context, AsyncSnapshot data) 
                              switch (data.connectionState) 
                                case ConnectionState.none:
                                  return Text(
                                    "none",
                                    style: TextStyle(color: Colors.black),
                                  );
                                case ConnectionState.waiting:
                                  return Center(
                                      child: CircularProgressIndicator(
                                    valueColor: AlwaysStoppedAnimation<Color>(
                                        Colors.black),
                                  ));
                                case ConnectionState.active:
                                  return Text('');
                                case ConnectionState.done:
                                  if (data.hasData) 
                                    return recentAlbumArt(
                                            albums[index].coverArt)
                                        .then((coverArtList) 
                                      return Image.network(coverArtList[index]);
                                    );
                                  
                              
                            );
                      ,
                    );
                  
              
            ),
      ),
    );
  


两个功能:

Future<List<Album>> fetchRecentlyAddedAlbums() async 
  try 
    var salt = randomToken(6);
    var token = makeToken("$password", "$salt");
    var uRL =
        "$server/rest/getAlbumList?u=$username&t=$token&s=$salt&v=$tapeOutVerison&c=$client$format&type=newest";
    var authresponse = await http.get(uRL);
    if (authresponse.statusCode == 200) 
      var jsondata = jsonDecode(authresponse.body);
      var data = apicallFromJson(jsondata);
      var aresponse = data.subsonicResponse.albumList.album;
      return aresponse;
     else 
      return null;
    
   catch (e) 
    return null;
  


//TODO: build the cover art fetching within the album list or build it outside
Future recentAlbumArt(String coverArtID) async 
  try 
    var salt = randomToken(6);
    var token = makeToken("$password", "$salt");
    var uRL =
        "$server/rest/getCoverArt/?u=$username&t=$token&s=$salt&v=$tapeOutVerison&c=$client$format&id=$coverArtID";
    var coverArtList = await http.get(uRL);
    return coverArtList;
   catch (e) 
    print(e);
  

【问题讨论】:

【参考方案1】:

你的嵌套FutureBuilder使用有误。而不是使用FutureBuilderbuilder 中的快照,而是再次调用recentAlbumArt 并返回它。

if (data.hasData) 
  return recentAlbumArt(//CALLING recentAlbumArt AGAIN HERE
    albums[index].coverArt)
      .then((coverArtList) 
        return Image.network(coverArtList[index]);
      );

改为使用FutureBuilder 提供的快照。

if (data.hasData) 
  return Image.network((data.data)[index]);

【讨论】:

谢谢!另一个问题是“类'响应'没有实例方法'[]'。”这与http请求的响应有关吗?我没有一个名为 response 的类。 是的,它与http请求的响应有关。您可能试图在其上调用对象类型不存在的东西。我建议为此创建一个单独的问题。

以上是关于根据闭包上下文的要求,返回类型“Future<Image>”不是“Widget”的主要内容,如果未能解决你的问题,请参考以下文章

根据闭包上下文的要求,返回类型“动态”不是“布尔”

FutureBuilder 错误:返回类型“对象?”不是闭包上下文所要求的“小部件”

如何将 Future<Widget> 作为小部件返回

Swift Combine:无法推断复杂的闭包返回类型错误

Swift学习笔记:闭包

Swift 中的尾随闭包语法是啥?