Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NewsApp/devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extensions:
86 changes: 50 additions & 36 deletions NewsApp/lib/components/customListTile.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import 'package:NewsApp/model/article_model.dart';
import 'package:NewsApp/models/topNews.model.dart';
import 'package:NewsApp/pages/articles_details_page.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

Widget customListTile(Article article, BuildContext context) {
Widget customListTile(Articles article, BuildContext context) {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(
article: article,
)));
context,
MaterialPageRoute(
builder: (context) => ArticlePage(
article: article,
),
),
);
},
child: Container(
margin: EdgeInsets.all(12.0),
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 3.0,
),
]),
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 3.0,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
Expand All @@ -32,39 +36,49 @@ Widget customListTile(Article article, BuildContext context) {
height: 200.0,
width: double.infinity,
decoration: BoxDecoration(
//let's add the height

image: DecorationImage(
image: NetworkImage(article.urlToImage), fit: BoxFit.cover),
image: NetworkImage(article.urlToImage ??
'https://via.placeholder.com/750x500.jpeg?text=Image+Error'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(12.0),
),
),
SizedBox(
height: 8.0,
),
SizedBox(height: 8.0),
Container(
padding: EdgeInsets.all(6.0),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(30.0),
),
child: Text(
article.source.name,
article.title ?? 'No Title',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
SizedBox(
height: 8.0,
),
Text(
article.title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
SizedBox(height: 8.0),
Container(
padding: EdgeInsets.all(6.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
article.source?.name ?? 'Unknown',
style: TextStyle(
color: Colors.blue,
),
),
Text(
article.publishedAt != null
? DateFormat('dd MMMM yyyy')
.format(DateTime.parse(article.publishedAt!))
: 'Unknown',
style: TextStyle(
color: Colors.blue,
),
),
],
),
)
),
],
),
),
Expand Down
94 changes: 94 additions & 0 deletions NewsApp/lib/components/everythingList.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import 'package:NewsApp/models/topNews.model.dart';
import 'package:NewsApp/pages/articles_details_page.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

Widget everythingListTile(Articles article, BuildContext context) {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ArticlePage(
article: article,
),
),
);
},
child: Container(
margin: EdgeInsets.all(12.0),
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 3.0,
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 150.0,
height: 200.0,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(article.urlToImage ??
'https://via.placeholder.com/750x500.jpeg?text=Image+Error'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(12.0),
),
),
SizedBox(width: 8.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
article.title ?? 'No Title',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
SizedBox(height: 8.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.account_circle, color: Colors.blue),
SizedBox(width: 4.0),
Text(
article.author ?? 'Unknown',
style: TextStyle(color: Colors.blue),
),
],
),
Row(
children: [
Icon(Icons.calendar_today, color: Colors.blue),
SizedBox(width: 4.0),
Text(
article.publishedAt != null
? DateFormat('dd MMMM yyyy')
.format(DateTime.parse(article.publishedAt!))
: 'Unknown',
style: TextStyle(color: Colors.blue),
),
],
),
],
),
],
),
),
],
),
),
);
}
13 changes: 13 additions & 0 deletions NewsApp/lib/helpers/api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:dio/dio.dart';

final dio = Dio();

api(String url, {String? method, String? data}) async {
final response = await dio.request(
url,
data: data,
options: Options(method: method),
);

return response;
}
107 changes: 83 additions & 24 deletions NewsApp/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import 'package:NewsApp/services/api_service.dart';
import 'package:NewsApp/components/everythingList.dart';
import 'package:NewsApp/models/topNews.model.dart';
import 'package:NewsApp/providers/news.provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'components/customListTile.dart';
import 'model/article_model.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
return ChangeNotifierProvider<NewsProvider>(
create: (context) => NewsProvider(),
child: MaterialApp(
home: HomePage(),
),
);
}
}
Expand All @@ -23,34 +28,88 @@ class HomePage extends StatefulWidget {
}

class _HomePageState extends State<HomePage> {
ApiService client = ApiService();
@override
void initState() {
super.initState();
Provider.of<NewsProvider>(context, listen: false).getTopNews();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("News App", style: TextStyle(color: Colors.black)),
backgroundColor: Colors.white,
title: Row(
children: <Widget>[
CircleAvatar(
radius: 20.0,
backgroundColor: Colors.blue,
),
SizedBox(width: 10.0),
Text(
"Mandiri News",
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
],
),
),

//Now let's call the APi services with futurebuilder wiget
body: FutureBuilder(
future: client.getArticle(),
builder: (BuildContext context, AsyncSnapshot<List<Article>> snapshot) {
//let's check if we got a response or not
if (snapshot.hasData) {
//Now let's make a list of articles
List<Article> articles = snapshot.data;
return ListView.builder(
//Now let's create our custom List tile
itemCount: articles.length,
itemBuilder: (context, index) =>
customListTile(articles[index], context),
body: Consumer<NewsProvider>(
builder: (context, newsProvider, child) {
if (newsProvider.isLoading) {
return Center(child: CircularProgressIndicator(color: Colors.blue));
} else if (newsProvider.resNews != null) {
List<Articles>? articles = newsProvider.resNews!.articles!;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView.builder(
itemCount: articles.length,
itemBuilder: (context, index) {
if (index == 0) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Berita Terkini',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 20),
),
),
customListTile(articles[index], context),
],
);
} else {
if (index == 1) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'Semua Berita',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 20),
),
),
everythingListTile(articles[index], context),
],
);
} else {
return everythingListTile(articles[index], context);
}
}
},
),
),
],
);
} else {
return Center(child: Text("Failed to load news"));
}
return Center(
child: CircularProgressIndicator(),
);
},
),
);
Expand Down
Loading