diff --git a/mdc_100_series/analysis_options.yaml b/mdc_100_series/analysis_options.yaml new file mode 100644 index 0000000000..4163582097 --- /dev/null +++ b/mdc_100_series/analysis_options.yaml @@ -0,0 +1,3 @@ +analyzer: + enable-experiment: + - non-nullable diff --git a/mdc_100_series/lib/app.dart b/mdc_100_series/lib/app.dart index 73fe8cb3b7..f26dd99619 100644 --- a/mdc_100_series/lib/app.dart +++ b/mdc_100_series/lib/app.dart @@ -58,7 +58,7 @@ class _ShrineAppState extends State { } } -Route _getRoute(RouteSettings settings) { +Route? _getRoute(RouteSettings settings) { if (settings.name != '/login') { return null; } @@ -107,17 +107,17 @@ ThemeData _buildShrineTheme() { TextTheme _buildShrineTextTheme(TextTheme base) { return base.copyWith( - headline5: base.headline5.copyWith( + headline5: base.headline5!.copyWith( fontWeight: FontWeight.w500, ), - headline6: base.headline6.copyWith( + headline6: base.headline6!.copyWith( fontSize: 18.0 ), - caption: base.caption.copyWith( + caption: base.caption!.copyWith( fontWeight: FontWeight.w400, fontSize: 14.0, ), - bodyText1: base.bodyText1.copyWith( + bodyText1: base.bodyText1!.copyWith( fontWeight: FontWeight.w500, fontSize: 16.0, ), diff --git a/mdc_100_series/lib/backdrop.dart b/mdc_100_series/lib/backdrop.dart index 442054e839..c73ff98a4e 100644 --- a/mdc_100_series/lib/backdrop.dart +++ b/mdc_100_series/lib/backdrop.dart @@ -13,7 +13,6 @@ // limitations under the License. import 'package:flutter/material.dart'; -import 'package:meta/meta.dart'; import 'model/product.dart'; import 'login.dart'; @@ -22,12 +21,12 @@ const double _kFlingVelocity = 2.0; class _FrontLayer extends StatelessWidget { const _FrontLayer({ - Key key, + Key? key, this.onTap, - this.child, + required this.child, }) : super(key: key); - final VoidCallback onTap; + final VoidCallback? onTap; final Widget child; @override @@ -58,26 +57,27 @@ class _FrontLayer extends StatelessWidget { } class _BackdropTitle extends AnimatedWidget { - final Function onPress; + final void Function() onPress; final Widget frontTitle; final Widget backTitle; const _BackdropTitle({ - Key key, - Listenable listenable, - this.onPress, - @required this.frontTitle, - @required this.backTitle, - }) : assert(frontTitle != null), - assert(backTitle != null), + Key? key, + required Animation listenable, + required this.onPress, + required this.frontTitle, + required this.backTitle, + }) : _listenable = listenable, super(key: key, listenable: listenable); + final Animation _listenable; + @override Widget build(BuildContext context) { - final Animation animation = this.listenable; + final Animation animation = _listenable; return DefaultTextStyle( - style: Theme.of(context).primaryTextTheme.headline6, + style: Theme.of(context)!.primaryTextTheme.headline6!, softWrap: false, overflow: TextOverflow.ellipsis, child: Row(children: [ @@ -158,16 +158,12 @@ class Backdrop extends StatefulWidget { final Widget backTitle; const Backdrop({ - @required this.currentCategory, - @required this.frontLayer, - @required this.backLayer, - @required this.frontTitle, - @required this.backTitle, - }) : assert(currentCategory != null), - assert(frontLayer != null), - assert(backLayer != null), - assert(frontTitle != null), - assert(backTitle != null); + required this.currentCategory, + required this.frontLayer, + required this.backLayer, + required this.frontTitle, + required this.backTitle, + }); @override _BackdropState createState() => _BackdropState(); @@ -176,7 +172,7 @@ class Backdrop extends StatefulWidget { class _BackdropState extends State with SingleTickerProviderStateMixin { final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop'); - AnimationController _controller; + late AnimationController _controller; @override void initState() { diff --git a/mdc_100_series/lib/category_menu_page.dart b/mdc_100_series/lib/category_menu_page.dart index 0cf9e4206a..bae531e2e6 100644 --- a/mdc_100_series/lib/category_menu_page.dart +++ b/mdc_100_series/lib/category_menu_page.dart @@ -13,7 +13,6 @@ // limitations under the License. import 'package:flutter/material.dart'; -import 'package:meta/meta.dart'; import 'colors.dart'; import 'model/product.dart'; @@ -24,16 +23,15 @@ class CategoryMenuPage extends StatelessWidget { final List _categories = Category.values; const CategoryMenuPage({ - Key key, - @required this.currentCategory, - @required this.onCategoryTap, - }) : assert(currentCategory != null), - assert(onCategoryTap != null); + Key? key, + required this.currentCategory, + required this.onCategoryTap, + }); Widget _buildCategory(Category category, BuildContext context) { final categoryString = category.toString().replaceAll('Category.', '').toUpperCase(); - final ThemeData theme = Theme.of(context); + final ThemeData theme = Theme.of(context)!; return GestureDetector( onTap: () => onCategoryTap(category), child: category == currentCategory @@ -57,7 +55,7 @@ class CategoryMenuPage extends StatelessWidget { padding: EdgeInsets.symmetric(vertical: 16.0), child: Text( categoryString, - style: theme.textTheme.bodyText1.copyWith( + style: theme.textTheme.bodyText1!.copyWith( color: kShrineBrown900.withAlpha(153) ), textAlign: TextAlign.center, diff --git a/mdc_100_series/lib/login.dart b/mdc_100_series/lib/login.dart index d01d26d122..79abe25a8a 100644 --- a/mdc_100_series/lib/login.dart +++ b/mdc_100_series/lib/login.dart @@ -39,7 +39,7 @@ class _LoginPageState extends State { SizedBox(height: 16.0), Text( 'SHRINE', - style: Theme.of(context).textTheme.headline5, + style: Theme.of(context)!.textTheme.headline5, ), ], ), @@ -96,7 +96,7 @@ class _LoginPageState extends State { } class AccentColorOverride extends StatelessWidget { - const AccentColorOverride({Key key, this.color, this.child}) + const AccentColorOverride({Key? key, required this.color, required this.child}) : super(key: key); final Color color; @@ -106,7 +106,7 @@ class AccentColorOverride extends StatelessWidget { Widget build(BuildContext context) { return Theme( child: child, - data: Theme.of(context).copyWith( + data: Theme.of(context)!.copyWith( accentColor: color, brightness: Brightness.dark, ), diff --git a/mdc_100_series/lib/model/product.dart b/mdc_100_series/lib/model/product.dart index 5df0ad197b..10644f0431 100755 --- a/mdc_100_series/lib/model/product.dart +++ b/mdc_100_series/lib/model/product.dart @@ -12,22 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:flutter/foundation.dart'; - enum Category { all, 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); + required this.category, + required this.id, + required this.isFeatured, + required this.name, + required this.price, + }); final Category category; final int id; diff --git a/mdc_100_series/lib/supplemental/asymmetric_view.dart b/mdc_100_series/lib/supplemental/asymmetric_view.dart index 6b5be2be47..199ecd5f6b 100644 --- a/mdc_100_series/lib/supplemental/asymmetric_view.dart +++ b/mdc_100_series/lib/supplemental/asymmetric_view.dart @@ -20,10 +20,10 @@ import 'product_columns.dart'; class AsymmetricView extends StatelessWidget { final List products; - AsymmetricView({Key key, this.products}); + AsymmetricView({Key? key, required this.products}); List _buildColumns(BuildContext context) { - if (products == null || products.isEmpty) { + if (products.isEmpty) { return []; } @@ -36,7 +36,7 @@ class AsymmetricView extends StatelessWidget { /// helpers for creating the index of the product list that will correspond /// to the index of the list of columns. return List.generate(_listItemCount(products.length), (int index) { - double width = .59 * MediaQuery.of(context).size.width; + double width = .59 * MediaQuery.of(context)!.size.width; Widget column; if (index % 2 == 0) { /// Even cases diff --git a/mdc_100_series/lib/supplemental/cut_corners_border.dart b/mdc_100_series/lib/supplemental/cut_corners_border.dart index 6837a09922..097930252e 100644 --- a/mdc_100_series/lib/supplemental/cut_corners_border.dart +++ b/mdc_100_series/lib/supplemental/cut_corners_border.dart @@ -19,10 +19,10 @@ import 'package:flutter/widgets.dart'; class CutCornersBorder extends OutlineInputBorder { const CutCornersBorder({ - BorderSide borderSide: const BorderSide(), - BorderRadius borderRadius: const BorderRadius.all(Radius.circular(2.0)), - this.cut: 7.0, - double gapPadding: 2.0, + BorderSide borderSide = const BorderSide(), + BorderRadius borderRadius = const BorderRadius.all(Radius.circular(2.0)), + this.cut = 7.0, + double gapPadding = 2.0, }) : super( borderSide: borderSide, borderRadius: borderRadius, @@ -30,10 +30,10 @@ class CutCornersBorder extends OutlineInputBorder { @override CutCornersBorder copyWith({ - BorderSide borderSide, - BorderRadius borderRadius, - double gapPadding, - double cut, + BorderSide? borderSide, + BorderRadius? borderRadius, + double? gapPadding, + double? cut, }) { return CutCornersBorder( borderRadius: borderRadius ?? this.borderRadius, @@ -46,11 +46,11 @@ class CutCornersBorder extends OutlineInputBorder { final double cut; @override - ShapeBorder lerpFrom(ShapeBorder a, double t) { + ShapeBorder? lerpFrom(ShapeBorder? a, double t) { if (a is CutCornersBorder) { final CutCornersBorder outline = a; return CutCornersBorder( - borderRadius: BorderRadius.lerp(outline.borderRadius, borderRadius, t), + borderRadius: BorderRadius.lerp(outline.borderRadius, borderRadius, t)!, borderSide: BorderSide.lerp(outline.borderSide, borderSide, t), cut: cut, gapPadding: outline.gapPadding, @@ -60,11 +60,11 @@ class CutCornersBorder extends OutlineInputBorder { } @override - ShapeBorder lerpTo(ShapeBorder b, double t) { + ShapeBorder? lerpTo(ShapeBorder? b, double t) { if (b is CutCornersBorder) { final CutCornersBorder outline = b; return CutCornersBorder( - borderRadius: BorderRadius.lerp(borderRadius, outline.borderRadius, t), + borderRadius: BorderRadius.lerp(borderRadius, outline.borderRadius, t)!, borderSide: BorderSide.lerp(borderSide, outline.borderSide, t), cut: cut, gapPadding: outline.gapPadding, @@ -103,12 +103,11 @@ class CutCornersBorder extends OutlineInputBorder { void paint( Canvas canvas, Rect rect, { - double gapStart, + double? gapStart, double gapExtent: 0.0, double gapPercentage: 0.0, - TextDirection textDirection, + TextDirection? textDirection, }) { - assert(gapExtent != null); assert(gapPercentage >= 0.0 && gapPercentage <= 1.0); final Paint paint = borderSide.toPaint(); @@ -117,8 +116,8 @@ class CutCornersBorder extends OutlineInputBorder { canvas.drawPath(_notchedCornerPath(outer.middleRect), paint); } else { final double extent = - lerpDouble(0.0, gapExtent + gapPadding * 2.0, gapPercentage); - switch (textDirection) { + lerpDouble(0.0, gapExtent + gapPadding * 2.0, gapPercentage)!; + switch (textDirection!) { case TextDirection.rtl: { final Path path = _notchedCornerPath( diff --git a/mdc_100_series/lib/supplemental/product_card.dart b/mdc_100_series/lib/supplemental/product_card.dart index a062a38a2a..806490839b 100644 --- a/mdc_100_series/lib/supplemental/product_card.dart +++ b/mdc_100_series/lib/supplemental/product_card.dart @@ -18,8 +18,8 @@ import 'package:intl/intl.dart'; import '../model/product.dart'; class ProductCard extends StatelessWidget { - ProductCard({this.imageAspectRatio: 33 / 49, this.product}) - : assert(imageAspectRatio == null || imageAspectRatio > 0); + ProductCard({this.imageAspectRatio = 33 / 49, required this.product}) + : assert(imageAspectRatio > 0); final double imageAspectRatio; final Product product; @@ -30,7 +30,7 @@ class ProductCard extends StatelessWidget { Widget build(BuildContext context) { final NumberFormat formatter = NumberFormat.simpleCurrency( decimalDigits: 0, locale: Localizations.localeOf(context).toString()); - final ThemeData theme = Theme.of(context); + final ThemeData theme = Theme.of(context)!; final imageWidget = Image.asset( product.assetName, @@ -47,14 +47,14 @@ class ProductCard extends StatelessWidget { child: imageWidget, ), SizedBox( - height: kTextBoxHeight * MediaQuery.of(context).textScaleFactor, + height: kTextBoxHeight * MediaQuery.of(context)!.textScaleFactor, width: 121.0, child: Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - product == null ? '' : product.name, + product.name, style: theme.textTheme.headline6, softWrap: false, overflow: TextOverflow.ellipsis, @@ -62,7 +62,7 @@ class ProductCard extends StatelessWidget { ), SizedBox(height: 4.0), Text( - product == null ? '' : formatter.format(product.price), + formatter.format(product.price), style: theme.textTheme.subtitle2, ), ], diff --git a/mdc_100_series/lib/supplemental/product_columns.dart b/mdc_100_series/lib/supplemental/product_columns.dart index e02904532f..a06ad611e1 100644 --- a/mdc_100_series/lib/supplemental/product_columns.dart +++ b/mdc_100_series/lib/supplemental/product_columns.dart @@ -19,11 +19,12 @@ import 'product_card.dart'; class TwoProductCardColumn extends StatelessWidget { TwoProductCardColumn({ - this.bottom, + required this.bottom, this.top, - }) : assert(bottom != null); + }); - final Product bottom, top; + final Product bottom; + final Product? top; @override Widget build(BuildContext context) { @@ -45,7 +46,7 @@ class TwoProductCardColumn extends StatelessWidget { child: top != null ? ProductCard( imageAspectRatio: imageAspectRatio, - product: top, + product: top!, ) : SizedBox( height: heightOfCards > 0 ? heightOfCards : spacerHeight, @@ -66,7 +67,7 @@ class TwoProductCardColumn extends StatelessWidget { } class OneProductCardColumn extends StatelessWidget { - OneProductCardColumn({this.product}); + OneProductCardColumn({required this.product}); final Product product; diff --git a/mdc_100_series/pubspec.yaml b/mdc_100_series/pubspec.yaml index b04b0bd8db..96bd534939 100644 --- a/mdc_100_series/pubspec.yaml +++ b/mdc_100_series/pubspec.yaml @@ -1,10 +1,17 @@ name: Shrine description: Take your design up a notch and learn to use our advanced component backdrop menu. +environment: + sdk: '>=2.10.0-56.0.dev <2.11.0' + dependencies: flutter: sdk: flutter - intl: ^0.15.6 + intl: + # TODO: Use pub dependency once NNBD beta is released. + git: + url: https://github.com/dart-lang/intl.git + ref: bb23da2587087d051e2f51685143b5fdd47f621f cupertino_icons: ^0.1.0 shrine_images: 1.1.1