diff --git a/.gitignore b/.gitignore index ae1f183..07e7c4e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,10 @@ .pub/ /build/ +gen/ +bin/ +out/ + # Web related lib/generated_plugin_registrant.dart diff --git a/lib/home_widget.dart b/lib/home_widget.dart new file mode 100644 index 0000000..62dadb4 --- /dev/null +++ b/lib/home_widget.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'news/feed.dart'; + +class Home extends StatelessWidget { + final List _curSport = ['FootBall', Colors.green]; + + final List colorList = [ + const Item("FootBall", Colors.red), + const Item("Soccer", Colors.pinkAccent), + const Item('Baseball', Colors.yellow), + ]; + + var feed = Feed(); + + @override + Widget build(BuildContext context) { + int _currentBodyIndex = 0; + Item selectedSport; + + return StatefulBuilder( + builder: (context, StateSetter setState) => Scaffold( + appBar: AppBar( + centerTitle: true, + title: DropdownButton( + 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>((Item item) { + return DropdownMenuItem( + value: item, + child: SizedBox( + width: 100, + child: Text(item.name), + ), + ); + }).toList(), + ), + backgroundColor: _curSport[1], + ), + body: ListView( + children: [ + HorizontalNewsFeed(newsFeed: feed, title: Text("Basketball")), + HorizontalNewsFeed(newsFeed: feed, title: Text("Soccer")), + HorizontalNewsFeed(newsFeed: feed, title: Text("Football")), + HorizontalNewsFeed(newsFeed: feed, title: Text("Volleyball")), + ], + ), + bottomNavigationBar: BottomNavigationBar( + type: BottomNavigationBarType.fixed, + onTap: (int index) { + setState(() { + _currentBodyIndex = index; + }); + }, + currentIndex: _currentBodyIndex, + items: [ + BottomNavigationBarItem( + icon: new Icon(Icons.home), + title: new Text("Home"), + ), + BottomNavigationBarItem( + icon: new Icon(Icons.calendar_today), + title: new Text("Schedule")), + BottomNavigationBarItem( + icon: new Icon(Icons.table_chart), title: new Text("Scores")), + BottomNavigationBarItem( + icon: new Icon(Icons.assessment), title: new Text("Standings")), + BottomNavigationBarItem( + icon: new Icon(Icons.more_horiz), title: new Text("More")) + ], + ), + ), + ); + } +} + +class Item { + const Item(this.name, this.color); + + final String name; + final Color color; +} diff --git a/lib/home_widget2.dart b/lib/home_widget2.dart deleted file mode 100644 index 174614d..0000000 --- a/lib/home_widget2.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:flutter/material.dart'; -import 'placeholder_widget.dart'; - -class Home extends StatelessWidget { - final List _curSport = ['FootBall', Colors.green]; - - final List colorList = [ - const Item("FootBall", Colors.red), - const Item("Soccer", Colors.pinkAccent), - const Item('Baseball', Colors.yellow), - ]; - - final List _children = [ - PlaceholderWidget(Colors.white), - PlaceholderWidget(Colors.orange), - PlaceholderWidget(Colors.blue), - PlaceholderWidget(Colors.red), - PlaceholderWidget(Colors.black38), - ]; - - @override - Widget build(BuildContext context) { - int _currentBodyIndex = 0; - Item selectedSport; - - return StatefulBuilder( - builder: (context, StateSetter setState) => Scaffold( - appBar: AppBar( - centerTitle: true, - title: DropdownButton( - 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>((Item item) { - return DropdownMenuItem( - value: item, - child: SizedBox( - width: 100, - child: Text(item.name), - ), - ); - }).toList(), - ), - backgroundColor: _curSport[1], - ), - body: _children[_currentBodyIndex], - bottomNavigationBar: BottomNavigationBar( - type: BottomNavigationBarType.fixed, - onTap: (int index) { - setState(() { - _currentBodyIndex = index; - }); - }, - currentIndex: _currentBodyIndex, - items: [ - BottomNavigationBarItem( - icon: new Icon(Icons.home), - title: new Text("Home"), - ), - BottomNavigationBarItem( - icon: new Icon(Icons.calendar_today), - title: new Text("Schedule")), - BottomNavigationBarItem( - icon: new Icon(Icons.table_chart), - title: new Text("Scores")), - BottomNavigationBarItem( - icon: new Icon(Icons.assessment), - title: new Text("Standings")), - BottomNavigationBarItem( - icon: new Icon(Icons.more_horiz), title: new Text("More")) - ], - ), - )); - } -} - -class Item { - const Item(this.name, this.color); - - final String name; - final Color color; -} diff --git a/lib/main.dart b/lib/main.dart index 1fbfd6d..fa4f33e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'home_widget2.dart'; +import 'home_widget.dart'; void main() => runApp(App()); @@ -15,6 +15,7 @@ class App extends StatelessWidget{ ), home: MyHomePage(title: 'UNCC Sports Demo Home Page'),*/ debugShowCheckedModeBanner: false, + title: 'UNCC Athletics', home: Home(), ); } diff --git a/lib/news/article.dart b/lib/news/article.dart new file mode 100644 index 0000000..4acc3a5 --- /dev/null +++ b/lib/news/article.dart @@ -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 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: [ + 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, + ), + ), + ); + } +} diff --git a/lib/news/feed.dart b/lib/news/feed.dart new file mode 100644 index 0000000..f7faa62 --- /dev/null +++ b/lib/news/feed.dart @@ -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> 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: [ + ListTile( + title: title, + trailing: IconButton( + icon: Icon(Icons.navigate_next), + onPressed: () {}, + ), + ), + Expanded( + child: FutureBuilder( + future: newsFeed.getPage(1), + builder: (ctx, snapshot) { + if (!snapshot.hasData) { + return Center(child: CircularProgressIndicator()); + } else { + List
articles = snapshot.data; + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: articles.length, + itemBuilder: (ctx, idx) { + return ArticleCard( + article: articles[idx], + ); + }, + ); + } + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/placeholder_widget.dart b/lib/placeholder_widget.dart deleted file mode 100644 index 64e35a2..0000000 --- a/lib/placeholder_widget.dart +++ /dev/null @@ -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, - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index fcf6763..dd132b2 100644 --- a/pubspec.lock +++ b/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: diff --git a/pubspec.yaml b/pubspec.yaml index 958dc91..5d4a329 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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