From d2c3aeb345c4acd64e587469672a82953787903d Mon Sep 17 00:00:00 2001 From: Andrew Brogdon Date: Thu, 6 Sep 2018 10:11:58 -0700 Subject: [PATCH] Adding veggieseasons DetailsScreen. (#14) --- veggieseasons/lib/screens/details.dart | 147 +++++++++++++++++- veggieseasons/lib/styles.dart | 12 ++ .../lib/widgets/veggie_headline.dart | 6 +- 3 files changed, 159 insertions(+), 6 deletions(-) diff --git a/veggieseasons/lib/screens/details.dart b/veggieseasons/lib/screens/details.dart index 2ccd40db9..42681e606 100644 --- a/veggieseasons/lib/screens/details.dart +++ b/veggieseasons/lib/screens/details.dart @@ -4,18 +4,159 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:veggieseasons/data/model.dart'; +import 'package:veggieseasons/data/veggie.dart'; import 'package:veggieseasons/styles.dart'; +/// A circular widget that indicates in which seasons a particular veggie can be +/// harvested. It displays the first two letters of the season and uses a +/// different background color to represent each of the seasons as well. +class SeasonCircle extends StatelessWidget { + final Season season; + + SeasonCircle(this.season); + + String get _firstChars { + return '${season.toString().substring(7, 8).toUpperCase()}' + '${season.toString().substring(8, 9)}'; + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(4.0), + child: DecoratedBox( + decoration: BoxDecoration( + color: Styles.seasonColors[season], + borderRadius: BorderRadius.circular(25.0), + border: Styles.seasonBorder, + ), + child: SizedBox( + height: 50.0, + width: 50.0, + child: Center( + child: Text(_firstChars, style: Styles.seasonText), + ), + ), + ), + ); + } +} + class DetailsScreen extends StatelessWidget { + final int id; + + DetailsScreen(this.id); + + Widget _createFavoriteButton(bool isFav, VoidCallback onPressed) { + return CupertinoButton( + color: Styles.buttonColor, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + isFav ? Styles.checkedIcon : Styles.uncheckedIcon, + color: Styles.buttonIconColor, + ), + SizedBox(width: 4.0), + Text(isFav ? 'Saved to Garden' : 'Save to Garden'), + ], + ), + onPressed: onPressed, + ); + } + + Widget _createHeader(AppState model) { + final veggie = model.getVeggie(id); + + return SizedBox( + height: 200.0, + child: Stack( + children: [ + Positioned( + right: 0.0, + left: 0.0, + child: Image.asset( + veggie.imageAssetPath, + fit: BoxFit.cover, + ), + ), + Positioned( + bottom: 0.0, + left: 0.0, + right: 0.0, + child: DecoratedBox( + decoration: BoxDecoration( + gradient: Styles.shadowGradient, + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 50.0, 16.0, 16.0), + child: Text( + veggie.name, + style: Styles.subheadText, + ), + ), + ), + ), + ], + ), + ); + } + + Widget _createDetails(AppState model) { + final veggie = model.getVeggie(id); + + return Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Wrap( + children: + veggie.seasons.map((s) => SeasonCircle(s)).toList(), + ), + SizedBox(width: 8.0), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Text( + veggieCategoryNames[veggie.category].toUpperCase(), + style: Styles.minorText, + ), + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: Text(veggie.shortDescription), + ), + _createFavoriteButton(veggie.isFavorite, () { + model.toggleFavorite(veggie.id); + }), + ], + ), + ); + } + @override Widget build(BuildContext context) { + final model = ScopedModel.of(context, rebuildOnChange: true); + return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text('Details'), ), - backgroundColor: Styles.scaffoldBackground, - child: Center( - child: Text('Not yet implemented.'), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _createHeader(model), + _createDetails(model), + ], ), ); } diff --git a/veggieseasons/lib/styles.dart b/veggieseasons/lib/styles.dart index b9dbeae54..546c1bef7 100644 --- a/veggieseasons/lib/styles.dart +++ b/veggieseasons/lib/styles.dart @@ -77,6 +77,8 @@ abstract class Styles { static const buttonColor = Color(0xff007aff); + static const buttonIconColor = Color(0xffffffff); + static const searchBackground = Color(0xffe0e0e0); static const TextStyle searchText = TextStyle( @@ -116,4 +118,14 @@ abstract class Styles { fontFamily: CupertinoIcons.iconFont, fontPackage: CupertinoIcons.iconFontPackage, ); + + static const transparentColor = Color(0x00000000); + + static const shadowColor = Color(0xa0000000); + + static const shadowGradient = LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [transparentColor, shadowColor], + ); } diff --git a/veggieseasons/lib/widgets/veggie_headline.dart b/veggieseasons/lib/widgets/veggie_headline.dart index 7eeeb42ce..110a5bf47 100644 --- a/veggieseasons/lib/widgets/veggie_headline.dart +++ b/veggieseasons/lib/widgets/veggie_headline.dart @@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart'; import 'package:veggieseasons/data/veggie.dart'; +import 'package:veggieseasons/screens/details.dart'; import 'package:veggieseasons/styles.dart'; class VeggieHeadline extends StatelessWidget { @@ -34,9 +35,8 @@ class VeggieHeadline extends StatelessWidget { @override Widget build(BuildContext context) { return GestureDetector( - onTap: () { - /* TODO(redbrogdon): navigation forthcoming */ - }, + onTap: () => Navigator.of(context).push( + CupertinoPageRoute(builder: (context) => DetailsScreen(veggie.id))), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [