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
相关产品推荐
相关产品推荐

