1
1
import 'dart:async' ;
2
2
import 'dart:io' ;
3
3
4
- import 'package:cached_network_image/cached_network_image.dart' ;
5
4
import 'package:flutter/cupertino.dart' ;
6
5
import 'package:flutter/material.dart' ;
7
6
import 'package:flutter_bloc/flutter_bloc.dart' ;
8
7
import 'package:flutter_news_app/feature/data/model/categorynews/category_news_model.dart' ;
9
8
import 'package:flutter_news_app/feature/data/model/topheadlinesnews/top_headlines_news_response_model.dart' ;
10
9
import 'package:flutter_news_app/feature/presentation/bloc/topheadlinesnews/bloc.dart' ;
10
+ import 'package:flutter_news_app/feature/presentation/page/search/search_page.dart' ;
11
+ import 'package:flutter_news_app/feature/presentation/widget/widget_failure_message.dart' ;
12
+ import 'package:flutter_news_app/feature/presentation/widget/widget_item_news.dart' ;
11
13
import 'package:flutter_news_app/injection_container.dart' ;
12
14
import 'package:flutter_screenutil/flutter_screenutil.dart' ;
13
- import 'package:flutter_svg/flutter_svg.dart' ;
14
15
import 'package:intl/intl.dart' ;
15
16
16
17
class HomePage extends StatefulWidget {
@@ -101,9 +102,15 @@ class _HomePageState extends State<HomePage> {
101
102
),
102
103
GestureDetector (
103
104
onTap: () {
104
- // TODO: buat fitur pencarian
105
+ Navigator .push (
106
+ context,
107
+ MaterialPageRoute (builder: (context) => SearchPage ()),
108
+ );
105
109
},
106
- child: Icon (Icons .search),
110
+ child: Hero (
111
+ tag: 'iconSearch' ,
112
+ child: Icon (Icons .search),
113
+ ),
107
114
),
108
115
],
109
116
),
@@ -164,7 +171,8 @@ class _HomePageState extends State<HomePage> {
164
171
delegate: SliverChildBuilderDelegate (
165
172
(context, index) {
166
173
var itemArticle = listArticles[index];
167
- var dateTimePublishedAt = DateFormat ('yyyy-MM-ddTHH:mm:ssZ' ).parse (itemArticle.publishedAt, true );
174
+ var dateTimePublishedAt =
175
+ DateFormat ('yyyy-MM-ddTHH:mm:ssZ' ).parse (itemArticle.publishedAt, true );
168
176
var strPublishedAt = DateFormat ('MMM dd, yyyy HH:mm' ).format (dateTimePublishedAt);
169
177
if (index == 0 ) {
170
178
return _buildWidgetItemLatestNews (itemArticle, strPublishedAt);
@@ -190,7 +198,6 @@ class _HomePageState extends State<HomePage> {
190
198
Widget _buildWidgetContentNewsAndroid () {
191
199
return BlocBuilder <TopHeadlinesNewsBloc , TopHeadlinesNewsState >(
192
200
builder: (context, state) {
193
- debugPrint ('state: $state ' );
194
201
var listArticles = < ItemArticleTopHeadlinesNewsResponseModel > [];
195
202
if (state is LoadedTopHeadlinesNewsState ) {
196
203
listArticles.addAll (state.listArticles);
@@ -220,9 +227,7 @@ class _HomePageState extends State<HomePage> {
220
227
itemCount: listArticles.length,
221
228
),
222
229
),
223
- listArticles.isEmpty && state is FailureTopHeadlinesNewsState
224
- ? _buildWidgetFailureLoadData ()
225
- : Container (),
230
+ listArticles.isEmpty && state is FailureTopHeadlinesNewsState ? _buildWidgetFailureLoadData () : Container (),
226
231
],
227
232
);
228
233
},
@@ -234,26 +239,7 @@ class _HomePageState extends State<HomePage> {
234
239
child: Column (
235
240
mainAxisAlignment: MainAxisAlignment .center,
236
241
children: < Widget > [
237
- SvgPicture .asset (
238
- 'assets/svg/undraw_newspaper.svg' ,
239
- width: ScreenUtil .screenWidthDp / 3 ,
240
- height: ScreenUtil .screenWidthDp / 3 ,
241
- ),
242
- SizedBox (height: 24. h),
243
- Text (
244
- 'You seem to be offline' ,
245
- style: TextStyle (
246
- fontSize: 48. sp,
247
- fontWeight: FontWeight .w500,
248
- ),
249
- ),
250
- Text (
251
- 'Check your wi-fi connection or cellular data \n and try again.' ,
252
- style: TextStyle (
253
- fontSize: 36. sp,
254
- ),
255
- textAlign: TextAlign .center,
256
- ),
242
+ WidgetFailureMessage (),
257
243
RaisedButton (
258
244
onPressed: () {
259
245
if (Platform .isIOS) {
@@ -289,66 +275,84 @@ class _HomePageState extends State<HomePage> {
289
275
top: index == 1 ? 32. h : 16. h,
290
276
bottom: 16. h,
291
277
),
292
- child: SizedBox (
293
- height: 200. w,
294
- child: Row (
295
- crossAxisAlignment: CrossAxisAlignment .start,
278
+ child: WidgetItemNews (
279
+ itemArticle: itemArticle,
280
+ strPublishedAt: strPublishedAt,
281
+ ),
282
+ );
283
+ }
284
+
285
+ Widget _buildWidgetItemLatestNews (
286
+ ItemArticleTopHeadlinesNewsResponseModel itemArticle,
287
+ String strPublishedAt,
288
+ ) {
289
+ return GestureDetector (
290
+ onTap: () {
291
+ // TODO: buat fitur arahkan ke website detail berita
292
+ },
293
+ child: Container (
294
+ width: double .infinity,
295
+ height: ScreenUtil .screenHeightDp / 3 ,
296
+ decoration: BoxDecoration (
297
+ borderRadius: BorderRadius .circular (8.0 ),
298
+ image: DecorationImage (
299
+ image: NetworkImage (
300
+ itemArticle.urlToImage,
301
+ ),
302
+ fit: BoxFit .cover,
303
+ ),
304
+ ),
305
+ child: Stack (
296
306
children: < Widget > [
297
- ClipRRect (
298
- borderRadius: BorderRadius .circular (8.0 ),
299
- child: CachedNetworkImage (
300
- imageUrl: itemArticle.urlToImage,
301
- fit: BoxFit .cover,
302
- width: 200. w,
303
- height: 200. w,
304
- errorWidget: (context, url, error) {
305
- return ClipRRect (
306
- borderRadius: BorderRadius .circular (8.0 ),
307
- child: Image .asset (
308
- 'assets/images/img_not_found.jpg' ,
309
- fit: BoxFit .cover,
310
- width: 200. w,
311
- height: 200. w,
312
- ),
313
- );
314
- },
315
- placeholder: (context, url) {
316
- return ClipRRect (
317
- borderRadius: BorderRadius .circular (8.0 ),
318
- child: Image .asset (
319
- 'assets/images/img_placeholder.jpg' ,
320
- fit: BoxFit .cover,
321
- width: 200. w,
322
- height: 200. w,
323
- ),
324
- );
325
- },
307
+ Container (
308
+ width: double .infinity,
309
+ height: ScreenUtil .screenHeightDp / 3 ,
310
+ decoration: BoxDecoration (
311
+ borderRadius: BorderRadius .circular (8.0 ),
312
+ gradient: LinearGradient (
313
+ begin: Alignment .bottomCenter,
314
+ end: Alignment .topCenter,
315
+ colors: [
316
+ Colors .black,
317
+ Colors .black.withOpacity (0.0 ),
318
+ ],
319
+ stops: [
320
+ 0.0 ,
321
+ 1.0 ,
322
+ ],
323
+ ),
326
324
),
327
- ),
328
- SizedBox (width: 24. w),
329
- Expanded (
325
+ padding: EdgeInsets .all (48. w),
330
326
child: Column (
327
+ mainAxisAlignment: MainAxisAlignment .end,
331
328
crossAxisAlignment: CrossAxisAlignment .start,
332
329
children: < Widget > [
333
- Expanded (
330
+ Container (
331
+ decoration: BoxDecoration (
332
+ color: Colors .pink,
333
+ borderRadius: BorderRadius .circular (48 ),
334
+ ),
335
+ padding: EdgeInsets .symmetric (
336
+ horizontal: 28. w,
337
+ vertical: 14. w,
338
+ ),
334
339
child: Text (
335
- itemArticle.title,
336
- maxLines: 2 ,
337
- overflow: TextOverflow .ellipsis,
340
+ 'Latest News' ,
338
341
style: TextStyle (
339
- fontSize: 36. sp,
342
+ color: Colors .white,
343
+ fontSize: 28. sp,
344
+ fontWeight: FontWeight .w500,
340
345
),
341
346
),
342
347
),
343
- itemArticle.author == null
344
- ? Container ()
345
- : Text (
346
- itemArticle.author,
347
- style: TextStyle (
348
- color: Colors .grey,
349
- fontSize: 28. sp,
350
- ),
351
- ),
348
+ SizedBox (height: 16. h),
349
+ Text (
350
+ itemArticle.title,
351
+ style: TextStyle (
352
+ color: Colors .white,
353
+ fontSize: 42. sp,
354
+ ),
355
+ ),
352
356
Row (
353
357
crossAxisAlignment: CrossAxisAlignment .end,
354
358
children: < Widget > [
@@ -383,107 +387,6 @@ class _HomePageState extends State<HomePage> {
383
387
),
384
388
);
385
389
}
386
-
387
- Widget _buildWidgetItemLatestNews (
388
- ItemArticleTopHeadlinesNewsResponseModel itemArticle,
389
- String strPublishedAt,
390
- ) {
391
- return Container (
392
- width: double .infinity,
393
- height: ScreenUtil .screenHeightDp / 3 ,
394
- decoration: BoxDecoration (
395
- borderRadius: BorderRadius .circular (8.0 ),
396
- image: DecorationImage (
397
- image: NetworkImage (
398
- itemArticle.urlToImage,
399
- ),
400
- fit: BoxFit .cover,
401
- ),
402
- ),
403
- child: Stack (
404
- children: < Widget > [
405
- Container (
406
- width: double .infinity,
407
- height: ScreenUtil .screenHeightDp / 3 ,
408
- decoration: BoxDecoration (
409
- borderRadius: BorderRadius .circular (8.0 ),
410
- gradient: LinearGradient (
411
- begin: Alignment .bottomCenter,
412
- end: Alignment .topCenter,
413
- colors: [
414
- Colors .black,
415
- Colors .black.withOpacity (0.0 ),
416
- ],
417
- stops: [
418
- 0.0 ,
419
- 1.0 ,
420
- ],
421
- ),
422
- ),
423
- padding: EdgeInsets .all (48. w),
424
- child: Column (
425
- mainAxisAlignment: MainAxisAlignment .end,
426
- crossAxisAlignment: CrossAxisAlignment .start,
427
- children: < Widget > [
428
- Container (
429
- decoration: BoxDecoration (
430
- color: Colors .pink,
431
- borderRadius: BorderRadius .circular (48 ),
432
- ),
433
- padding: EdgeInsets .symmetric (
434
- horizontal: 28. w,
435
- vertical: 14. w,
436
- ),
437
- child: Text (
438
- 'Latest News' ,
439
- style: TextStyle (
440
- color: Colors .white,
441
- fontSize: 28. sp,
442
- fontWeight: FontWeight .w500,
443
- ),
444
- ),
445
- ),
446
- SizedBox (height: 16. h),
447
- Text (
448
- itemArticle.title,
449
- style: TextStyle (
450
- color: Colors .white,
451
- fontSize: 42. sp,
452
- ),
453
- ),
454
- Row (
455
- crossAxisAlignment: CrossAxisAlignment .end,
456
- children: < Widget > [
457
- Text (
458
- strPublishedAt,
459
- style: TextStyle (
460
- color: Colors .grey,
461
- fontSize: 24. sp,
462
- ),
463
- ),
464
- Text (
465
- ' | ' ,
466
- style: TextStyle (
467
- color: Colors .grey,
468
- fontSize: 28. sp,
469
- ),
470
- ),
471
- Text (
472
- itemArticle.source.name,
473
- style: TextStyle (
474
- color: Colors .grey,
475
- fontSize: 24. sp,
476
- ),
477
- ),
478
- ],
479
- ),
480
- ],
481
- ),
482
- ),
483
- ],
484
- ),
485
- );
486
- }
487
390
}
488
391
489
392
class WidgetCategoryNews extends StatefulWidget {
@@ -527,7 +430,8 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
527
430
indexCategorySelected = index;
528
431
});
529
432
var topHeadlinesNewsBloc = BlocProvider .of <TopHeadlinesNewsBloc >(context);
530
- topHeadlinesNewsBloc.add (ChangeCategoryTopHeadlinesNewsEvent (indexCategorySelected: indexCategorySelected));
433
+ topHeadlinesNewsBloc
434
+ .add (ChangeCategoryTopHeadlinesNewsEvent (indexCategorySelected: indexCategorySelected));
531
435
},
532
436
child: Container (
533
437
child: AnimatedContainer (
@@ -542,9 +446,9 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
542
446
),
543
447
border: indexCategorySelected == index
544
448
? Border .all (
545
- color: Colors .white,
546
- width: 2.0 ,
547
- )
449
+ color: Colors .white,
450
+ width: 2.0 ,
451
+ )
548
452
: null ,
549
453
),
550
454
child: Center (
@@ -562,11 +466,11 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
562
466
image: itemCategory.title.toLowerCase () == 'all'
563
467
? null
564
468
: DecorationImage (
565
- image: AssetImage (
566
- itemCategory.image,
567
- ),
568
- fit: BoxFit .cover,
569
- ),
469
+ image: AssetImage (
470
+ itemCategory.image,
471
+ ),
472
+ fit: BoxFit .cover,
473
+ ),
570
474
),
571
475
),
572
476
),
@@ -578,7 +482,6 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
578
482
}
579
483
}
580
484
581
-
582
485
class WidgetDateToday extends StatefulWidget {
583
486
@override
584
487
_WidgetDateTodayState createState () => _WidgetDateTodayState ();
0 commit comments