11import 'dart:async' ;
22import 'dart:io' ;
33
4- import 'package:cached_network_image/cached_network_image.dart' ;
54import 'package:flutter/cupertino.dart' ;
65import 'package:flutter/material.dart' ;
76import 'package:flutter_bloc/flutter_bloc.dart' ;
87import 'package:flutter_news_app/feature/data/model/categorynews/category_news_model.dart' ;
98import 'package:flutter_news_app/feature/data/model/topheadlinesnews/top_headlines_news_response_model.dart' ;
109import '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' ;
1113import 'package:flutter_news_app/injection_container.dart' ;
1214import 'package:flutter_screenutil/flutter_screenutil.dart' ;
13- import 'package:flutter_svg/flutter_svg.dart' ;
1415import 'package:intl/intl.dart' ;
1516
1617class HomePage extends StatefulWidget {
@@ -101,9 +102,15 @@ class _HomePageState extends State<HomePage> {
101102 ),
102103 GestureDetector (
103104 onTap: () {
104- // TODO: buat fitur pencarian
105+ Navigator .push (
106+ context,
107+ MaterialPageRoute (builder: (context) => SearchPage ()),
108+ );
105109 },
106- child: Icon (Icons .search),
110+ child: Hero (
111+ tag: 'iconSearch' ,
112+ child: Icon (Icons .search),
113+ ),
107114 ),
108115 ],
109116 ),
@@ -164,7 +171,8 @@ class _HomePageState extends State<HomePage> {
164171 delegate: SliverChildBuilderDelegate (
165172 (context, index) {
166173 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 );
168176 var strPublishedAt = DateFormat ('MMM dd, yyyy HH:mm' ).format (dateTimePublishedAt);
169177 if (index == 0 ) {
170178 return _buildWidgetItemLatestNews (itemArticle, strPublishedAt);
@@ -190,7 +198,6 @@ class _HomePageState extends State<HomePage> {
190198 Widget _buildWidgetContentNewsAndroid () {
191199 return BlocBuilder <TopHeadlinesNewsBloc , TopHeadlinesNewsState >(
192200 builder: (context, state) {
193- debugPrint ('state: $state ' );
194201 var listArticles = < ItemArticleTopHeadlinesNewsResponseModel > [];
195202 if (state is LoadedTopHeadlinesNewsState ) {
196203 listArticles.addAll (state.listArticles);
@@ -220,9 +227,7 @@ class _HomePageState extends State<HomePage> {
220227 itemCount: listArticles.length,
221228 ),
222229 ),
223- listArticles.isEmpty && state is FailureTopHeadlinesNewsState
224- ? _buildWidgetFailureLoadData ()
225- : Container (),
230+ listArticles.isEmpty && state is FailureTopHeadlinesNewsState ? _buildWidgetFailureLoadData () : Container (),
226231 ],
227232 );
228233 },
@@ -234,26 +239,7 @@ class _HomePageState extends State<HomePage> {
234239 child: Column (
235240 mainAxisAlignment: MainAxisAlignment .center,
236241 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 (),
257243 RaisedButton (
258244 onPressed: () {
259245 if (Platform .isIOS) {
@@ -289,66 +275,84 @@ class _HomePageState extends State<HomePage> {
289275 top: index == 1 ? 32. h : 16. h,
290276 bottom: 16. h,
291277 ),
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 (
296306 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+ ),
326324 ),
327- ),
328- SizedBox (width: 24. w),
329- Expanded (
325+ padding: EdgeInsets .all (48. w),
330326 child: Column (
327+ mainAxisAlignment: MainAxisAlignment .end,
331328 crossAxisAlignment: CrossAxisAlignment .start,
332329 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+ ),
334339 child: Text (
335- itemArticle.title,
336- maxLines: 2 ,
337- overflow: TextOverflow .ellipsis,
340+ 'Latest News' ,
338341 style: TextStyle (
339- fontSize: 36. sp,
342+ color: Colors .white,
343+ fontSize: 28. sp,
344+ fontWeight: FontWeight .w500,
340345 ),
341346 ),
342347 ),
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+ ),
352356 Row (
353357 crossAxisAlignment: CrossAxisAlignment .end,
354358 children: < Widget > [
@@ -383,107 +387,6 @@ class _HomePageState extends State<HomePage> {
383387 ),
384388 );
385389 }
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- }
487390}
488391
489392class WidgetCategoryNews extends StatefulWidget {
@@ -527,7 +430,8 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
527430 indexCategorySelected = index;
528431 });
529432 var topHeadlinesNewsBloc = BlocProvider .of <TopHeadlinesNewsBloc >(context);
530- topHeadlinesNewsBloc.add (ChangeCategoryTopHeadlinesNewsEvent (indexCategorySelected: indexCategorySelected));
433+ topHeadlinesNewsBloc
434+ .add (ChangeCategoryTopHeadlinesNewsEvent (indexCategorySelected: indexCategorySelected));
531435 },
532436 child: Container (
533437 child: AnimatedContainer (
@@ -542,9 +446,9 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
542446 ),
543447 border: indexCategorySelected == index
544448 ? Border .all (
545- color: Colors .white,
546- width: 2.0 ,
547- )
449+ color: Colors .white,
450+ width: 2.0 ,
451+ )
548452 : null ,
549453 ),
550454 child: Center (
@@ -562,11 +466,11 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
562466 image: itemCategory.title.toLowerCase () == 'all'
563467 ? null
564468 : 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+ ),
570474 ),
571475 ),
572476 ),
@@ -578,7 +482,6 @@ class _WidgetCategoryNewsState extends State<WidgetCategoryNews> {
578482 }
579483}
580484
581-
582485class WidgetDateToday extends StatefulWidget {
583486 @override
584487 _WidgetDateTodayState createState () => _WidgetDateTodayState ();
0 commit comments