diff --git a/MDC-102/complete/.gitignore b/MDC-102/complete/.gitignore new file mode 100644 index 0000000000..af17aaf5b6 --- /dev/null +++ b/MDC-102/complete/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +.atom/ +.dart_tool/ +.idea +.vscode/ +.packages +.pub/ +build/ +ios/.generated/ +packages +.flutter-plugins diff --git a/MDC-102/complete/.metadata b/MDC-102/complete/.metadata new file mode 100644 index 0000000000..809f919d3d --- /dev/null +++ b/MDC-102/complete/.metadata @@ -0,0 +1,8 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 5a58b36e36b8d7aace89d3950e6deb307956a6a0 + channel: beta diff --git a/MDC-102/complete/assets/0-1.jpg b/MDC-102/complete/assets/0-1.jpg new file mode 100644 index 0000000000..532e9ba6a7 Binary files /dev/null and b/MDC-102/complete/assets/0-1.jpg differ diff --git a/MDC-102/complete/assets/1-1.jpg b/MDC-102/complete/assets/1-1.jpg new file mode 100644 index 0000000000..908f09b487 Binary files /dev/null and b/MDC-102/complete/assets/1-1.jpg differ diff --git a/MDC-102/complete/assets/2-1.jpg b/MDC-102/complete/assets/2-1.jpg new file mode 100644 index 0000000000..f64f4eaaa8 Binary files /dev/null and b/MDC-102/complete/assets/2-1.jpg differ diff --git a/MDC-102/complete/assets/2.0x/diamond.png b/MDC-102/complete/assets/2.0x/diamond.png new file mode 100644 index 0000000000..602e2ea516 Binary files /dev/null and b/MDC-102/complete/assets/2.0x/diamond.png differ diff --git a/MDC-102/complete/assets/3-1.jpg b/MDC-102/complete/assets/3-1.jpg new file mode 100644 index 0000000000..7ea93995f7 Binary files /dev/null and b/MDC-102/complete/assets/3-1.jpg differ diff --git a/MDC-102/complete/assets/3.0x/diamond.png b/MDC-102/complete/assets/3.0x/diamond.png new file mode 100644 index 0000000000..78af7cd648 Binary files /dev/null and b/MDC-102/complete/assets/3.0x/diamond.png differ diff --git a/MDC-102/complete/assets/diamond.png b/MDC-102/complete/assets/diamond.png new file mode 100644 index 0000000000..1978a0a5ab Binary files /dev/null and b/MDC-102/complete/assets/diamond.png differ diff --git a/MDC-102/complete/lib/app.dart b/MDC-102/complete/lib/app.dart new file mode 100644 index 0000000000..e3d0b85e2c --- /dev/null +++ b/MDC-102/complete/lib/app.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +import 'home.dart'; +import 'login.dart'; + +class ShrineApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Shrine', + home: HomePage(), + initialRoute: '/login', + onGenerateRoute: _getRoute, + ); + } + + Route _getRoute(RouteSettings settings) { + if (settings.name != '/login') { + return null; + } + + return MaterialPageRoute( + settings: settings, + builder: (BuildContext context) => LoginPage(), + fullscreenDialog: true, + ); + } +} diff --git a/MDC-102/complete/lib/home.dart b/MDC-102/complete/lib/home.dart new file mode 100644 index 0000000000..afa3ef8ace --- /dev/null +++ b/MDC-102/complete/lib/home.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import 'model/data.dart'; +import 'model/product.dart'; + +class HomePage extends StatefulWidget { + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + List _buildGridCards() { + List products = getAllProducts(); + + if (products == null || products.isEmpty) { + return const []; + } + + final ThemeData theme = Theme.of(context); + final NumberFormat formatter = NumberFormat.simpleCurrency( + locale: Localizations.localeOf(context).toString()); + + return products.map((product) { + return Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 18 / 11, + child: Image.asset( + 'assets/${product.id}-1.jpg', + fit: BoxFit.fitWidth, + ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // TODO(larche): Make headline6 when available + Text( + product.name, + style: theme.textTheme.title, + maxLines: 1, + ), + SizedBox(height: 8.0), + // TODO(larche): Make subtitle2 when available + Text( + formatter.format(product.price), + style: theme.textTheme.body2, + ), + ], + ), + ), + ), + ], + ), + ); + }).toList(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.menu), + onPressed: () { + print('Menu button'); + }, + ), + title: Text('SHRINE'), + actions: [ + IconButton( + icon: Icon(Icons.search), + onPressed: () { + print('Search button'); + }, + ), + IconButton( + icon: Icon(Icons.tune), + onPressed: () { + print('Filter button'); + }, + ), + ], + ), + body: Center( + child: GridView.count( + crossAxisCount: 2, + children: _buildGridCards(), + padding: EdgeInsets.all(16.0), + mainAxisSpacing: 8.0, + childAspectRatio: 8.0 / 9.0, + ), + ), + ); + } +} diff --git a/MDC-102/complete/lib/login.dart b/MDC-102/complete/lib/login.dart new file mode 100644 index 0000000000..68e741b07c --- /dev/null +++ b/MDC-102/complete/lib/login.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; + +class LoginPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 24.0), + children: [ + SizedBox(height: 80.0), + Column( + children: [ + Image.asset('assets/diamond.png'), + SizedBox(height: 16.0), + Text('SHRINE'), + ], + ), + SizedBox(height: 120.0), + TextField( + decoration: InputDecoration( + filled: true, + labelText: 'Username', + ), + ), + SizedBox(height: 12.0), + TextField( + decoration: InputDecoration( + filled: true, + labelText: 'Password', + ), + obscureText: true, + ), + ButtonBar( + children: [ + FlatButton( + child: Text('CANCEL'), + onPressed: null, + ), + RaisedButton( + child: Text('NEXT'), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ) + ], + ), + ), + ); + } +} diff --git a/MDC-102/complete/lib/main.dart b/MDC-102/complete/lib/main.dart new file mode 100644 index 0000000000..9cac46625b --- /dev/null +++ b/MDC-102/complete/lib/main.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +import 'app.dart'; + +void main() => runApp(ShrineApp()); diff --git a/MDC-102/complete/lib/model/data.dart b/MDC-102/complete/lib/model/data.dart new file mode 100644 index 0000000000..b84eddbafa --- /dev/null +++ b/MDC-102/complete/lib/model/data.dart @@ -0,0 +1,34 @@ +import 'product.dart'; + +List getAllProducts() { + return [ + Product( + category: Category.home, + id: 0, + isFeatured: true, + name: 'Tab Can', + price: 35, + ), + Product( + category: Category.accessories, + id: 1, + isFeatured: false, + name: 'Pineapple Wallpaper', + price: 80, + ), + Product( + category: Category.clothing, + id: 2, + isFeatured: false, + name: 'Tab & Fresca Cooler', + price: 100, + ), + Product( + category: Category.home, + id: 3, + isFeatured: false, + name: 'Capris', + price: 5, + ), + ]; +} diff --git a/MDC-102/complete/lib/model/product.dart b/MDC-102/complete/lib/model/product.dart new file mode 100644 index 0000000000..9275a1d30b --- /dev/null +++ b/MDC-102/complete/lib/model/product.dart @@ -0,0 +1,26 @@ +import 'package:flutter/foundation.dart'; + +enum Category { none, accessories, clothing, home } + +class Product { + const Product({ + @required this.category, + @required this.id, + @required this.isFeatured, + @required this.name, + @required this.price, + }) : assert(category != null), + assert(id != null), + assert(isFeatured != null), + assert(name != null), + assert(price != null); + + final Category category; + final int id; + final bool isFeatured; + final String name; + final int price; + + @override + String toString() => "$name (id=$id)"; +} diff --git a/MDC-102/complete/pubspec.yaml b/MDC-102/complete/pubspec.yaml new file mode 100644 index 0000000000..871668481b --- /dev/null +++ b/MDC-102/complete/pubspec.yaml @@ -0,0 +1,23 @@ +name: mdc_101_complete +description: > + Learn the basics of using Material Components by building a simple app with core components. + +dependencies: + flutter: + sdk: flutter + intl: "^0.15.4" + + cupertino_icons: ^0.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true + assets: + - assets/diamond.png + - assets/0-1.jpg + - assets/1-1.jpg + - assets/2-1.jpg + - assets/3-1.jpg