Restructured files, and added the basic navigation
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -30,6 +30,10 @@
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
gen/
|
||||
bin/
|
||||
out/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
|
||||
91
lib/news/article.dart
Normal file
91
lib/news/article.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Article {
|
||||
final int id;
|
||||
final String type;
|
||||
final String sport;
|
||||
final String title;
|
||||
final String mediumHeadline;
|
||||
final String url;
|
||||
final String summary;
|
||||
final String thumbUrl;
|
||||
|
||||
Article(
|
||||
this.id, {
|
||||
this.type,
|
||||
this.sport,
|
||||
this.title,
|
||||
this.mediumHeadline,
|
||||
this.url,
|
||||
this.summary,
|
||||
this.thumbUrl,
|
||||
});
|
||||
|
||||
factory Article.fromJson(Map<String, dynamic> json) {
|
||||
return Article(
|
||||
json['id'],
|
||||
type: json['type'],
|
||||
sport: json['sport'],
|
||||
title: json['title'],
|
||||
mediumHeadline: json['medium_headline'],
|
||||
url: json['url'],
|
||||
summary: json['summary'],
|
||||
thumbUrl: json['thumb']['url'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ArticleCard extends StatelessWidget {
|
||||
const ArticleCard({
|
||||
Key key,
|
||||
@required this.article,
|
||||
this.numCards = 1.25,
|
||||
}) : super(key: key);
|
||||
|
||||
final Article article;
|
||||
final double numCards;
|
||||
|
||||
double widthIn(BuildContext context) {
|
||||
return MediaQuery.of(context).size.width / numCards;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var decoration = BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(
|
||||
article.thumbUrl,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
);
|
||||
|
||||
var body = Column(
|
||||
verticalDirection: VerticalDirection.up,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
article.mediumHeadline,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
return SizedBox(
|
||||
width: widthIn(context),
|
||||
child: Card(
|
||||
semanticContainer: true,
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
child: Container(
|
||||
decoration: decoration,
|
||||
child: body,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
74
lib/news/feed.dart
Normal file
74
lib/news/feed.dart
Normal file
@@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'article.dart';
|
||||
|
||||
class Feed {
|
||||
static final cobraBase = "https://www.ncaa.com/ncaa/cobra";
|
||||
|
||||
Future<List<Article>> getPage(int page, {int size = 10}) async {
|
||||
var url = '$cobraBase/school-content/charlotte,$page,$size';
|
||||
http.Response response = await http.get(url);
|
||||
Iterable articles = json.decode(response.body);
|
||||
return articles.map((e) => Article.fromJson(e)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
class HorizontalNewsFeed extends StatelessWidget {
|
||||
final Feed newsFeed;
|
||||
final Widget title;
|
||||
final double numCards;
|
||||
|
||||
const HorizontalNewsFeed({
|
||||
Key key,
|
||||
@required this.newsFeed,
|
||||
@required this.title,
|
||||
this.numCards = 3.25,
|
||||
}) : super(key: key);
|
||||
|
||||
double heightIn(BuildContext context) {
|
||||
return MediaQuery.of(context).size.height / numCards;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: heightIn(context),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: title,
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.navigate_next),
|
||||
onPressed: () => Navigator.pushNamed(context, '/Sport'),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: FutureBuilder(
|
||||
future: newsFeed.getPage(1),
|
||||
builder: (ctx, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
List<Article> articles = snapshot.data;
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: articles.length,
|
||||
itemBuilder: (ctx, idx) {
|
||||
return ArticleCard(
|
||||
article: articles[idx],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PlaceholderWidget extends StatelessWidget{
|
||||
final Color color;
|
||||
PlaceholderWidget(this.color,);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: color,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../placeholder_widget.dart';
|
||||
import '../news/feed.dart';
|
||||
|
||||
|
||||
class Home extends StatelessWidget {
|
||||
final List<Widget> _children = [
|
||||
PlaceholderWidget(Colors.white),
|
||||
PlaceholderWidget(Colors.orange),
|
||||
PlaceholderWidget(Colors.blue),
|
||||
PlaceholderWidget(Colors.red),
|
||||
PlaceholderWidget(Colors.black38),
|
||||
];
|
||||
|
||||
final feed = Feed(); //was var not final
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -17,12 +13,15 @@ class Home extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
centerTitle: false,
|
||||
title: Text("49ers"),
|
||||
),
|
||||
body: _children[4],
|
||||
floatingActionButton: FloatingActionButton(
|
||||
backgroundColor: Colors.green,
|
||||
child: Icon(Icons.arrow_forward_ios),
|
||||
onPressed: () => Navigator.pushNamed(context, '/Sport'),
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text("Basketball")),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text("Soccer")),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text("Football")),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text("Volleyball")),
|
||||
],
|
||||
),
|
||||
drawer: Drawer(
|
||||
child: ListView(
|
||||
@@ -32,7 +31,7 @@ class Home extends StatelessWidget {
|
||||
'Drawer Header',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../news/feed.dart';
|
||||
|
||||
class Sport extends StatelessWidget {
|
||||
final List<Object> _curSport = ['FootBall', Colors.green];
|
||||
|
||||
final List<Item> colorList = <Item>[
|
||||
const Item("FootBall", Colors.red),
|
||||
const Item('FootBall', Colors.green),
|
||||
const Item("BasketBall", Colors.red),
|
||||
const Item("Soccer", Colors.pinkAccent),
|
||||
const Item('Baseball', Colors.yellow),
|
||||
const Item('Baseball', Colors.orange),
|
||||
];
|
||||
|
||||
final feed = Feed(); // was var not final
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Item selectedSport;
|
||||
@@ -16,34 +20,76 @@ class Sport extends StatelessWidget {
|
||||
return StatefulBuilder(
|
||||
builder: (context, StateSetter setState) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: DropdownButton<Item>(
|
||||
value: selectedSport,
|
||||
icon: Icon(Icons.arrow_drop_down),
|
||||
iconSize: 24,
|
||||
style: TextStyle(color: Colors.black),
|
||||
iconEnabledColor: Colors.white,
|
||||
onChanged: (Item value) {
|
||||
setState(() {
|
||||
selectedSport = value;
|
||||
_curSport[0] = selectedSport.name;
|
||||
_curSport[1] = selectedSport.color;
|
||||
});
|
||||
},
|
||||
items: colorList.map<DropdownMenuItem<Item>>((Item item) {
|
||||
return DropdownMenuItem<Item>(
|
||||
value: item,
|
||||
child: SizedBox(
|
||||
width: 100,
|
||||
child: Text(item.name),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
centerTitle: false,
|
||||
title: buildDropdownButton(selectedSport, setState),
|
||||
backgroundColor: _curSport[1],
|
||||
),
|
||||
body: Center(
|
||||
child: Text("Sports Page Body"),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text(_curSport[0])),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text(_curSport[0])),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text(_curSport[0])),
|
||||
HorizontalNewsFeed(newsFeed: feed, title: Text(_curSport[0])),
|
||||
],
|
||||
),
|
||||
drawer: Drawer(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
DrawerHeader(
|
||||
child: Text(
|
||||
'Drawer Header',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: IconButton(
|
||||
icon: Icon(Icons.home),
|
||||
onPressed: () => Navigator.pushNamed(context, '/'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DropdownButtonHideUnderline buildDropdownButton(
|
||||
Item selectedSport, StateSetter setState) {
|
||||
return DropdownButtonHideUnderline(
|
||||
child: DropdownButton<Item>(
|
||||
value: selectedSport,
|
||||
icon: Icon(Icons.arrow_drop_down),
|
||||
iconSize: 28,
|
||||
style: TextStyle(color: Colors.black, fontSize: 28),
|
||||
iconEnabledColor: Colors.white,
|
||||
hint: Text(
|
||||
_curSport[0],
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold),
|
||||
),
|
||||
onChanged: (Item value) {
|
||||
setState(() {
|
||||
selectedSport = value;
|
||||
_curSport[0] = selectedSport.name;
|
||||
_curSport[1] = selectedSport.color;
|
||||
});
|
||||
},
|
||||
items: colorList.map<DropdownMenuItem<Item>>((Item item) {
|
||||
return DropdownMenuItem<Item>(
|
||||
value: item,
|
||||
child: SizedBox(
|
||||
child: Text(item.name),
|
||||
width: 110,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
14
pubspec.lock
14
pubspec.lock
@@ -74,6 +74,20 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.0+4"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -20,6 +20,8 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
http: ^0.12.0+4
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.2
|
||||
|
||||
Reference in New Issue
Block a user