質問編集履歴

1

コードを記入しました

2021/12/28 01:35

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -3,3 +3,389 @@
3
3
 
4
4
 
5
5
  おそらく非同期処理で先にwidgetが更新されその後にhttp通信が行われているため表示されないのだと思われるのですが,どうすればいいのでしょうか?
6
+
7
+ view.dart
8
+
9
+ ```dart
10
+
11
+ class _Articles extends HookConsumerWidget {
12
+
13
+ @override
14
+
15
+ Widget build(BuildContext context, WidgetRef ref) {
16
+
17
+ final viewModel = ref.watch(articleViewModel.notifier);
18
+
19
+ final aState = ref.watch(articleViewModel.notifier).state;
20
+
21
+ print(aState);
22
+
23
+
24
+
25
+ return RefreshIndicator(
26
+
27
+ onRefresh: () async {
28
+
29
+ print(aState);
30
+
31
+ await viewModel.refreshArticles();
32
+
33
+ },
34
+
35
+ child:
36
+
37
+ ListView.builder(
38
+
39
+ itemCount: aState.articles.length,
40
+
41
+ itemBuilder: (context, int index) {
42
+
43
+ if (index == (aState.articles.length - 1) && aState.hasNext) {
44
+
45
+ viewModel.getArticles();
46
+
47
+ return const LinearProgressIndicator();
48
+
49
+ }
50
+
51
+ return _articleItem(context, aState.articles[index]);
52
+
53
+ },
54
+
55
+ ),
56
+
57
+ );
58
+
59
+ }
60
+
61
+
62
+
63
+ Widget _articleItem(context, article) {
64
+
65
+ return GestureDetector(
66
+
67
+ child: Container(
68
+
69
+ padding: const EdgeInsets.all(15.0),
70
+
71
+ decoration: const BoxDecoration(
72
+
73
+ border: Border(
74
+
75
+ bottom: BorderSide(
76
+
77
+ color: Color(0x1e333333),
78
+
79
+ width: 1,
80
+
81
+ ),
82
+
83
+ ),
84
+
85
+ ),
86
+
87
+ child: Column(
88
+
89
+ crossAxisAlignment: CrossAxisAlignment.start,
90
+
91
+ children: <Widget>[
92
+
93
+ _articleUser(article.user),
94
+
95
+ const SizedBox(
96
+
97
+ height: 10.0,
98
+
99
+ ),
100
+
101
+ Text(article.title),
102
+
103
+ const SizedBox(
104
+
105
+ height: 10.0,
106
+
107
+ ),
108
+
109
+ Wrap(
110
+
111
+ spacing: 7.5,
112
+
113
+ children: <Widget>[
114
+
115
+ for (int i = 0; i < article.tags.length; i++)
116
+
117
+ _articleTag(article.tags[i])
118
+
119
+ ],
120
+
121
+ ),
122
+
123
+ const SizedBox(
124
+
125
+ height: 5.0,
126
+
127
+ ),
128
+
129
+ _articleCreatedAt(article.createdAt),
130
+
131
+ ],
132
+
133
+ ),
134
+
135
+ ),
136
+
137
+ onTap: () {
138
+
139
+ Navigator.of(context).push(
140
+
141
+ MaterialPageRoute(
142
+
143
+ builder: (context) => ArticleDetailPage(
144
+
145
+ article: article,
146
+
147
+ ),
148
+
149
+ ),
150
+
151
+ );
152
+
153
+ },
154
+
155
+ );
156
+
157
+ }
158
+
159
+
160
+
161
+ Widget _articleUser(user) {
162
+
163
+ final userId = user.id;
164
+
165
+ return Row(
166
+
167
+ children: [
168
+
169
+ CircleAvatar(
170
+
171
+ backgroundImage: NetworkImage(user.profileImageUrl),
172
+
173
+ radius: 12.0,
174
+
175
+ child: const Text(''),
176
+
177
+ ),
178
+
179
+ const SizedBox(width: 8.0),
180
+
181
+ Text('@$userId'),
182
+
183
+ ],
184
+
185
+ );
186
+
187
+ }
188
+
189
+
190
+
191
+ Widget _articleTag(tag) {
192
+
193
+ return GestureDetector(
194
+
195
+ child: Text(
196
+
197
+ tag['name'],
198
+
199
+ style: const TextStyle(
200
+
201
+ decoration: TextDecoration.underline,
202
+
203
+ ),
204
+
205
+ ),
206
+
207
+ onTap: () {
208
+
209
+ // ignore: avoid_print
210
+
211
+ print(tag['name']);
212
+
213
+ },
214
+
215
+ );
216
+
217
+ }
218
+
219
+
220
+
221
+ Widget _articleCreatedAt(createdAt) {
222
+
223
+ DateFormat format = DateFormat('yyyy-MM-dd');
224
+
225
+ String date = format.format(DateTime.parse(createdAt).toLocal());
226
+
227
+
228
+
229
+ return SizedBox(
230
+
231
+ width: double.infinity,
232
+
233
+ child: Text(
234
+
235
+ '$dateに投稿',
236
+
237
+ textAlign: TextAlign.right,
238
+
239
+ ),
240
+
241
+ );
242
+
243
+ }
244
+
245
+ }
246
+
247
+
248
+
249
+ ```
250
+
251
+ viewmodel.dart
252
+
253
+
254
+
255
+ ```dart
256
+
257
+ final articleViewModel = StateNotifierProvider(
258
+
259
+ (_) => ArticleViewModel(
260
+
261
+ ArticleRepository(),
262
+
263
+ ),
264
+
265
+ );
266
+
267
+
268
+
269
+ class ArticleViewModel extends StateNotifier<ArticlesState> {
270
+
271
+ ArticleViewModel(this.repository) : super(const ArticlesState()) {
272
+
273
+ getArticles();
274
+
275
+ }
276
+
277
+
278
+
279
+ final ArticleRepository repository;
280
+
281
+
282
+
283
+ int _page = 1;
284
+
285
+ bool _isLoading = false;
286
+
287
+
288
+
289
+ Future<void> getArticles() async {
290
+
291
+ if (_isLoading || !state.hasNext) {
292
+
293
+ return;
294
+
295
+ }
296
+
297
+
298
+
299
+ _isLoading = true;
300
+
301
+
302
+
303
+ final articles = await repository.fetchArticles(_page, state.keyword);
304
+
305
+ // print(articles);
306
+
307
+ final newArticles = [...state.articles, ...articles];
308
+
309
+ // print(newArticles);
310
+
311
+
312
+
313
+ if (articles.length % 20 != 0 || articles.length == 0) {
314
+
315
+ state = state.copyWith(
316
+
317
+ hasNext: false,
318
+
319
+ );
320
+
321
+ }
322
+
323
+
324
+
325
+ state = state.copyWith(
326
+
327
+ articles: newArticles,
328
+
329
+ );
330
+
331
+ // print(state);
332
+
333
+ print(_isLoading);
334
+
335
+ _page++;
336
+
337
+ _isLoading = false;
338
+
339
+ print(_isLoading);
340
+
341
+ }
342
+
343
+
344
+
345
+ Future<void> setQuery(String keyword) async {
346
+
347
+ state = state.copyWith(
348
+
349
+ articles: [],
350
+
351
+ keyword: keyword,
352
+
353
+ hasNext: true,
354
+
355
+ );
356
+
357
+
358
+
359
+ _page = 1;
360
+
361
+ }
362
+
363
+
364
+
365
+ Future<void> refreshArticles() async {
366
+
367
+ state = state.copyWith(
368
+
369
+ articles: [],
370
+
371
+ hasNext: true,
372
+
373
+ );
374
+
375
+
376
+
377
+ _page = 1;
378
+
379
+
380
+
381
+ getArticles();
382
+
383
+ }
384
+
385
+ }
386
+
387
+
388
+
389
+ ```
390
+
391
+ viewmodelのapiはprintで出力されていました