繁体   English   中英

Flutter - 尝试显示从 JSON 获取的推文列表到 ListView

[英]Flutter - Attempting to display a list of tweets fetched from JSON onto ListView

我正在尝试使用 Flutter 的 HTTP 库和 Twitter 的 API 端点获取推文列表,然后使用 Flutter tweet_ui将推文列表显示到 ListView 小部件上。 我能够获取正确工作的推文列表,并得到一个 JSON 响应。 但是,我目前正在尝试解码 JSON response.body 并将其保存到 List 中,以便稍后在将其传递给我正在使用的 tweet_ui 方法后进行编码。 使用我在下面显示的代码,我继续得到这个红色错误屏幕,错误提示“期望类型为 'String' 的值,但得到类型为 '_Future < dynamic >' 的值之一”。 我已经多次尝试使用从函数到函数传递的不同类型,但似乎不起作用。 我还尝试将小部件包装在未来的构建器周围,但这似乎并不奏效。 知道我可能做错了什么吗?

Future 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"
    });

String jsonData = response.body;   

return jsonData;
}

用于使用来自 Twitter API 的 HTTP 库获取推文的函数

List getListOfTweets(var jsonData) {
List<dynamic> tweets = [];

tweets = convert.jsonDecode(jsonData);

return tweets;
}

用于希望转换在 Json 中提取的每条推文以添加到列表中的函数。

List<dynamic> tweets = handler.getListOfTweets(handler.getTweetJson());

@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(title: Text("Tweets")),
  body: Column(children: <Widget>[
    Expanded(
      child: ListView.builder(
          itemCount: tweets.length,
          itemBuilder: (context, index) {
            return Container(
                child: Column(
              children: [
                EmbeddedTweetView.fromTweet(
                  Tweet.fromRawJson(
                    convert.jsonEncode(tweets[index]),
                  ),
                )
              ],
            ));
          }),
    ),
  ]),
);

}

使用 ListView 的小部件

var tweetJson = handler.getTweetJson();

@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(title: Text("Tweets")),
  body: Container(
    child: Card(
      child: FutureBuilder(
        future: tweetJson,
        builder: (context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
            return Container(
              child: const Center(
                child: Text('Loading. . .'),
              ),
            );
          } else {
            var tweets =
                List<String>.from(convert.jsonDecode(snapshot.data));
            return ListView.builder(
                itemCount: tweets.length,
                itemBuilder: (context, index) {
                  return Container(
                      child: Column(
                    children: [
                      EmbeddedTweetView.fromTweet(
                        Tweet.fromRawJson(
                          convert.jsonEncode(tweets[index]),
                        ),
                      )
                    ],
                  ));
                });
          }
        },
      ),
    ),
  ),
);

}

使用 Future Builder 的替代小部件

我建议

  1. 为推文创建类模型

  2. 从 api 获取 json 数据,然后将其解码为 json ,将其映射到创建的类,然后将其转换为列表(返回推文列表的未来构建器),或者如果您使用状态管理(跳到步骤 4)。

  3. 使用状态管理即。 提供者或 Getx

下面是如果你使用 provider 作为状态管理

  1. 如果您使用的提供程序使用更改通知程序并List<your_tweet_class>文列表保存为列表数据类型,例如List<your_tweet_class> ,现在您可以使用指定类的Provider.of(context)访问它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM