Skip to content

Commit 764d946

Browse files
authored
Merge pull request CoderJava#29 from CoderJava/feature/detail-news
Create detail news feature
2 parents 65657a9 + f1ad11d commit 764d946

File tree

4 files changed

+179
-159
lines changed

4 files changed

+179
-159
lines changed

lib/feature/presentation/page/home/home_page.dart

+60-47
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:flutter_news_app/feature/presentation/widget/widget_item_news.da
1313
import 'package:flutter_news_app/injection_container.dart';
1414
import 'package:flutter_screenutil/flutter_screenutil.dart';
1515
import 'package:intl/intl.dart';
16+
import 'package:url_launcher/url_launcher.dart';
1617

1718
class HomePage extends StatefulWidget {
1819
@override
@@ -55,9 +56,6 @@ class _HomePageState extends State<HomePage> {
5556
@override
5657
Widget build(BuildContext context) {
5758
ScreenUtil.init(context);
58-
var mediaQueryData = MediaQuery.of(context);
59-
var paddingTop = mediaQueryData.padding.top;
60-
var paddingBottom = mediaQueryData.padding.bottom;
6159
return Scaffold(
6260
body: BlocProvider<TopHeadlinesNewsBloc>(
6361
create: (context) => topHeadlinesNewsBloc,
@@ -78,53 +76,62 @@ class _HomePageState extends State<HomePage> {
7876
}
7977
}
8078
},
81-
child: Container(
82-
width: double.infinity,
83-
color: Color(0xFFEFF5F5),
84-
padding: EdgeInsets.symmetric(
85-
vertical: 24.h,
86-
),
87-
child: Column(
88-
crossAxisAlignment: CrossAxisAlignment.start,
89-
children: <Widget>[
90-
SizedBox(height: paddingTop),
91-
Padding(
92-
padding: EdgeInsets.symmetric(horizontal: 48.w),
93-
child: Row(
79+
child: Stack(
80+
children: [
81+
Container(
82+
width: double.infinity,
83+
height: double.infinity,
84+
color: Color(0xFFEFF5F5),
85+
),
86+
SafeArea(
87+
child: Container(
88+
width: double.infinity,
89+
color: Color(0xFFEFF5F5),
90+
padding: EdgeInsets.symmetric(
91+
vertical: 24.h,
92+
),
93+
child: Column(
94+
crossAxisAlignment: CrossAxisAlignment.start,
9495
children: <Widget>[
95-
Expanded(
96-
child: Text(
97-
'Daily News',
98-
style: TextStyle(
99-
fontSize: 48.sp,
100-
),
96+
Padding(
97+
padding: EdgeInsets.symmetric(horizontal: 48.w),
98+
child: Row(
99+
children: <Widget>[
100+
Expanded(
101+
child: Text(
102+
'Daily News',
103+
style: TextStyle(
104+
fontSize: 48.sp,
105+
),
106+
),
107+
),
108+
GestureDetector(
109+
onTap: () {
110+
Navigator.push(
111+
context,
112+
MaterialPageRoute(builder: (context) => SearchPage()),
113+
);
114+
},
115+
child: Hero(
116+
tag: 'iconSearch',
117+
child: Icon(Icons.search),
118+
),
119+
),
120+
],
101121
),
102122
),
103-
GestureDetector(
104-
onTap: () {
105-
Navigator.push(
106-
context,
107-
MaterialPageRoute(builder: (context) => SearchPage()),
108-
);
109-
},
110-
child: Hero(
111-
tag: 'iconSearch',
112-
child: Icon(Icons.search),
113-
),
123+
WidgetDateToday(),
124+
SizedBox(height: 24.h),
125+
WidgetCategoryNews(listCategories: listCategories),
126+
SizedBox(height: 24.h),
127+
Expanded(
128+
child: Platform.isIOS ? _buildWidgetContentNewsIOS() : _buildWidgetContentNewsAndroid(),
114129
),
115130
],
116131
),
117132
),
118-
WidgetDateToday(),
119-
SizedBox(height: 24.h),
120-
WidgetCategoryNews(listCategories: listCategories),
121-
SizedBox(height: 24.h),
122-
Expanded(
123-
child: Platform.isIOS ? _buildWidgetContentNewsIOS() : _buildWidgetContentNewsAndroid(),
124-
),
125-
SizedBox(height: paddingBottom),
126-
],
127-
),
133+
),
134+
],
128135
),
129136
),
130137
),
@@ -287,12 +294,18 @@ class _HomePageState extends State<HomePage> {
287294
String strPublishedAt,
288295
) {
289296
return GestureDetector(
290-
onTap: () {
291-
// TODO: buat fitur arahkan ke website detail berita
297+
onTap: () async {
298+
if (await canLaunch(itemArticle.url)) {
299+
await launch(itemArticle.url);
300+
} else {
301+
Scaffold.of(context).showSnackBar(SnackBar(
302+
content: Text('Couldn\'t open detail news'),
303+
));
304+
}
292305
},
293306
child: Container(
294307
width: double.infinity,
295-
height: ScreenUtil.screenHeightDp / 3,
308+
height: ScreenUtil.screenWidthDp / 1.7,
296309
decoration: BoxDecoration(
297310
borderRadius: BorderRadius.circular(8.0),
298311
image: DecorationImage(
@@ -306,7 +319,7 @@ class _HomePageState extends State<HomePage> {
306319
children: <Widget>[
307320
Container(
308321
width: double.infinity,
309-
height: ScreenUtil.screenHeightDp / 3,
322+
height: ScreenUtil.screenWidthDp / 1.7,
310323
decoration: BoxDecoration(
311324
borderRadius: BorderRadius.circular(8.0),
312325
gradient: LinearGradient(

lib/feature/presentation/page/search/search_page.dart

+110-103
Original file line numberDiff line numberDiff line change
@@ -42,119 +42,126 @@ class _SearchPageState extends State<SearchPage> {
4242
@override
4343
Widget build(BuildContext context) {
4444
ScreenUtil.init(context);
45-
var mediaQueryData = MediaQuery.of(context);
46-
var paddingTop = mediaQueryData.padding.top;
47-
var paddingBottom = mediaQueryData.padding.bottom;
4845
return Scaffold(
4946
body: BlocProvider<TopHeadlinesNewsBloc>(
5047
create: (context) => topHeadlinesNewsBloc,
51-
child: Container(
52-
color: Color(0xFFEFF5F5),
53-
width: double.infinity,
54-
padding: EdgeInsets.symmetric(
55-
horizontal: 48.w,
56-
vertical: 24.h,
57-
),
58-
child: Column(
59-
children: <Widget>[
60-
SizedBox(height: paddingTop),
61-
Row(
62-
children: <Widget>[
63-
GestureDetector(
64-
onTap: () {
65-
Navigator.pop(context);
66-
},
67-
child: Icon(
68-
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
69-
),
70-
),
71-
SizedBox(width: 24.w),
72-
Expanded(
73-
child: Container(
74-
decoration: BoxDecoration(
75-
border: Border.all(color: Colors.grey),
76-
borderRadius: BorderRadius.circular(99.0),
77-
),
78-
padding: EdgeInsets.symmetric(horizontal: 36.w),
79-
child: Row(
80-
children: <Widget>[
81-
Expanded(
82-
child: TextField(
83-
controller: controllerKeyword,
84-
decoration: InputDecoration(
85-
isDense: true,
86-
hintText: 'Searching something?',
87-
hintStyle: TextStyle(
88-
fontSize: 36.sp,
89-
color: Colors.grey,
90-
),
91-
enabledBorder: InputBorder.none,
92-
focusedBorder: InputBorder.none,
93-
),
94-
style: TextStyle(
95-
fontSize: 36.sp,
96-
),
97-
),
48+
child: Stack(
49+
children: [
50+
Container(
51+
width: double.infinity,
52+
height: double.infinity,
53+
color: Color(0xFFEFF5F5),
54+
),
55+
SafeArea(
56+
child: Container(
57+
color: Color(0xFFEFF5F5),
58+
width: double.infinity,
59+
padding: EdgeInsets.symmetric(
60+
vertical: 24.h,
61+
horizontal: 48.w,
62+
),
63+
child: Column(
64+
children: <Widget>[
65+
Row(
66+
children: <Widget>[
67+
GestureDetector(
68+
onTap: () {
69+
Navigator.pop(context);
70+
},
71+
child: Icon(
72+
Platform.isIOS ? Icons.arrow_back_ios : Icons.arrow_back,
9873
),
99-
Hero(
100-
tag: 'iconSearch',
101-
child: Focus(
102-
focusNode: focusNodeIconSearch,
103-
child: Icon(
104-
Icons.search,
105-
size: 48.w,
106-
),
74+
),
75+
SizedBox(width: 24.w),
76+
Expanded(
77+
child: Container(
78+
decoration: BoxDecoration(
79+
border: Border.all(color: Colors.grey),
80+
borderRadius: BorderRadius.circular(99.0),
81+
),
82+
padding: EdgeInsets.symmetric(horizontal: 36.w),
83+
child: Row(
84+
children: <Widget>[
85+
Expanded(
86+
child: TextField(
87+
controller: controllerKeyword,
88+
decoration: InputDecoration(
89+
isDense: true,
90+
hintText: 'Searching something?',
91+
hintStyle: TextStyle(
92+
fontSize: 36.sp,
93+
color: Colors.grey,
94+
),
95+
enabledBorder: InputBorder.none,
96+
focusedBorder: InputBorder.none,
97+
),
98+
style: TextStyle(
99+
fontSize: 36.sp,
100+
),
101+
),
102+
),
103+
Hero(
104+
tag: 'iconSearch',
105+
child: Focus(
106+
focusNode: focusNodeIconSearch,
107+
child: Icon(
108+
Icons.search,
109+
size: 48.w,
110+
),
111+
),
112+
),
113+
],
107114
),
108115
),
109-
],
110-
),
116+
),
117+
],
111118
),
112-
),
113-
],
114-
),
115-
SizedBox(height: 16.h),
116-
Expanded(
117-
child: BlocBuilder<TopHeadlinesNewsBloc, TopHeadlinesNewsState>(
118-
builder: (context, state) {
119-
if (state is LoadingTopHeadlinesNewsState) {
120-
return Center(
121-
child: Platform.isIOS ? CupertinoActivityIndicator() : CircularProgressIndicator(),
122-
);
123-
} else if (state is FailureTopHeadlinesNewsState) {
124-
return WidgetFailureMessage();
125-
} else if (state is SearchSuccessTopHeadlinesNewsState) {
126-
var listArticles = state.listArticles;
127-
if (listArticles.isEmpty) {
128-
return WidgetFailureMessage(
129-
errorTitle: 'Data not found',
130-
errorSubtitle: 'Hm, we couldn\'t find what you were looking for.',
131-
);
132-
} else {
133-
return ListView.builder(
134-
padding: EdgeInsets.only(bottom: paddingBottom),
135-
itemBuilder: (context, index) {
136-
var itemArticle = listArticles[index];
137-
var dateTimePublishedAt =
138-
DateFormat('yyy-MM-ddTHH:mm:ssZ').parse(itemArticle.publishedAt, true);
139-
var strPublishedAt = DateFormat('MMM dd, yyyy HH:mm').format(dateTimePublishedAt);
140-
return Padding(
141-
padding: EdgeInsets.symmetric(vertical: 16.h),
142-
child: WidgetItemNews(
143-
itemArticle: itemArticle,
144-
strPublishedAt: strPublishedAt,
145-
),
119+
SizedBox(height: 16.h),
120+
Expanded(
121+
child: BlocBuilder<TopHeadlinesNewsBloc, TopHeadlinesNewsState>(
122+
builder: (context, state) {
123+
if (state is LoadingTopHeadlinesNewsState) {
124+
return Center(
125+
child: Platform.isIOS ? CupertinoActivityIndicator() : CircularProgressIndicator(),
146126
);
147-
},
148-
itemCount: listArticles.length,
149-
);
150-
}
151-
}
152-
return Container();
153-
},
127+
} else if (state is FailureTopHeadlinesNewsState) {
128+
return WidgetFailureMessage();
129+
} else if (state is SearchSuccessTopHeadlinesNewsState) {
130+
var listArticles = state.listArticles;
131+
if (listArticles.isEmpty) {
132+
return WidgetFailureMessage(
133+
errorTitle: 'Data not found',
134+
errorSubtitle: 'Hm, we couldn\'t find what you were looking for.',
135+
);
136+
} else {
137+
return ListView.builder(
138+
padding: EdgeInsets.zero,
139+
itemBuilder: (context, index) {
140+
var itemArticle = listArticles[index];
141+
var dateTimePublishedAt =
142+
DateFormat('yyy-MM-ddTHH:mm:ssZ').parse(itemArticle.publishedAt, true);
143+
var strPublishedAt = DateFormat('MMM dd, yyyy HH:mm').format(dateTimePublishedAt);
144+
return Padding(
145+
padding: EdgeInsets.symmetric(vertical: 16.h),
146+
child: WidgetItemNews(
147+
itemArticle: itemArticle,
148+
strPublishedAt: strPublishedAt,
149+
),
150+
);
151+
},
152+
itemCount: listArticles.length,
153+
);
154+
}
155+
}
156+
return Container();
157+
},
158+
),
159+
),
160+
],
154161
),
155162
),
156-
],
157-
),
163+
),
164+
],
158165
),
159166
),
160167
);

0 commit comments

Comments
 (0)