You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用Twitter API获取推文使用tweet_ui在ListView渲染报错咨询

错误原因&解决方法

1. 非FutureBuilder版本报错的核心原因

你调用handler.getListOfTweets(handler.getTweetJson())时,getTweetJson()是异步方法,没有加await前缀时返回的是Future类型对象,不是方法最终返回的JSON字符串,所以传给getListOfTweets的参数类型不符合要求,直接触发类型不匹配报错。

2. FutureBuilder版本报错的核心原因

  • Twitter API v2的返回结果是顶层Map结构,推文列表存储在返回值的data字段中,你直接将jsonDecode(snapshot.data)的结果转为List<String>属于结构解析错误,jsonDecode(snapshot.data)本身是Map类型,无法直接转为List。
  • 推文列表的每一项是Map结构,不是String类型,强制转为List<String>也会触发类型错误。
  • 你的getListOfTweets方法本身也存在解析逻辑错误:Twitter接口返回的JSON解码后是完整响应Map,需要取其中的data字段才能拿到推文数组,不能直接赋值给tweets变量。

修正后的代码

先修正解析方法

// 注意参数明确指定为String类型
List<Map<String,dynamic>> getListOfTweets(String jsonData) {
  // 先解码整个响应
  Map<String,dynamic> fullResponse = convert.jsonDecode(jsonData);
  // 取data字段作为推文列表返回
  return List<Map<String,dynamic>>.from(fullResponse['data'] ?? []);
}

修正后的FutureBuilder组件代码

// 异步方法明确标注返回类型
Future<String> getTweetJson() async {
  Map<String, String> params = {
    'exclude': 'retweets',
    'expansions':
        'attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,geo.place_id,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id',
    'tweet.fields':
        'attachments,author_id,context_annotations,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang,possibly_sensitive,public_metrics,reply_settings,source,text',
    'user.fields':
        'created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified',
    'place.fields':
        'contained_within,country,country_code,full_name,geo,id,name,place_type',
    'media.fields':
        'duration_ms,height,media_key,preview_image_url,type,url,width,public_metrics,non_public_metrics,organic_metrics,promoted_metrics'
  };

  var response = await http.get(
      Uri.https('api.twitter.com', '2/users/IDnumber/tweets', params),
      headers: {
        "Authorization":
            "Bearer bearerToken"
      });
  return response.body;
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("Tweets")),
    body: Card(
      child: FutureBuilder<String>(
        future: getTweetJson(),
        builder: (context, AsyncSnapshot<String> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: Text('Loading. . .'));
          }
          if (snapshot.hasError) {
            return Center(child: Text('加载失败:${snapshot.error}'));
          }
          // 解析得到推文列表
          List<Map<String,dynamic>> tweets = getListOfTweets(snapshot.data!);
          return ListView.builder(
            itemCount: tweets.length,
            itemBuilder: (context, index) {
              return EmbeddedTweetView.fromTweet(
                Tweet.fromRawJson(convert.jsonEncode(tweets[index])),
              );
            },
          );
        },
      ),
    ),
  );
}

额外优化建议

可以直接把Tweet.fromRawJson的步骤放到解析阶段,避免重复序列化/反序列化操作,提升性能。


内容的提问来源于stack exchange,提问作者aaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:06:11