#flutter #dart
Вопрос:
Я пытаюсь получить список твитов, используя HTTP-библиотеку Flutter и конечную точку API Twitter, а затем отобразить список твитов в виджете ListView, используя библиотеку Flutter tweet_ui. Мне удалось получить корректную выборку списка твитов, и я получаю ответ JSON. Однако в настоящее время я пытаюсь декодировать ответ JSON.тело и сохраните его в списке для последующего кодирования, как только я передам его используемому мной методу 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;
}
Функция, используемая для извлечения твитов с использованием HTTP-библиотеки из Twitter API
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:
Я предлагаю
- Создайте модель класса для tweet
- Получите данные json из api, затем декодируйте их в json, после сопоставьте их с созданным классом, а затем преобразуйте в list (будущий конструктор возвращает список твитов) или, если вы используете управление состоянием (перейдите к шагу 4).
- Используйте управление состоянием ie. Поставщик или Getx
Следующее, если вы используете поставщика в качестве управления состоянием
- если ваш провайдер использует уведомление об изменении и сохраняет список твитов в виде списка типа данных, что-то вроде
List<your_tweet_class>
, и теперь вы можете получить к нему доступProvider.of(context)
с помощью указанного класса
Комментарии:
1. У вас есть пример пример будущего разработчика, возвращающего список твитов?
2. Я не уверен, что лучше всего создать модель класса для tweet, поскольку функция Tweet.fromRawJson() принимает строку, а библиотека tweet_ui уже поставляется с классом Tweet .