Unverified Commit 21e80274 authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Migrate Flutter Gallery test to null safety (#70116)

parent 43e1d159
......@@ -29,15 +29,13 @@ dependencies:
coverage: 0.14.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 2.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib: 0.16.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dart_style: 1.3.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
html: 0.14.0+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http: 0.12.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
intl: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
intl_translation: 0.17.10+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
intl: 0.17.0-nullsafety.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
isolate: 2.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.3-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -50,7 +48,6 @@ dependencies:
package_config: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pedantic: 1.10.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
petitparser: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pool: 1.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf: 0.7.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -77,4 +74,4 @@ dependencies:
flutter:
uses-material-design: true
# PUBSPEC CHECKSUM: 77af
# PUBSPEC CHECKSUM: 2c1c
......@@ -9,42 +9,23 @@ dependencies:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: 0.16.1
intl_translation: 0.17.10+1
intl: 0.17.0-nullsafety.2
http: 0.12.2
isolate: 2.0.3
_fe_analyzer_shared: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
analyzer: 0.39.17 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 1.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.1.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
charcode: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
cli_util: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.15.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 2.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib: 0.16.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dart_style: 1.3.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
html: 0.14.0+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.3-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.3.0-nullsafety.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_interop: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_io: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
package_config: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pedantic: 1.10.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
petitparser: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.8.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 0.9.7+15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
......@@ -53,19 +34,33 @@ dev_dependencies:
sdk: flutter
test: 1.16.0-nullsafety.9
_fe_analyzer_shared: 7.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
analyzer: 0.39.17 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
archive: 2.0.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 1.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
cli_util: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 0.14.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 2.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib: 0.16.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.0.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
html: 0.14.0+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.3-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 0.11.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.10-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 0.9.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_interop: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_io: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 1.4.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
package_config: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pool: 1.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf: 0.7.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_packages_handler: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_static: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -78,11 +73,13 @@ dev_dependencies:
test_api: 0.2.19-nullsafety.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_core: 0.3.12-nullsafety.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 5.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 0.9.7+15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
# PUBSPEC CHECKSUM: b21f
# PUBSPEC CHECKSUM: 4b8b
......@@ -20,10 +20,10 @@ class SectionDetail {
this.imageAsset,
this.imageAssetPackage,
});
final String title;
final String subtitle;
final String imageAsset;
final String imageAssetPackage;
final String? title;
final String? subtitle;
final String? imageAsset;
final String? imageAssetPackage;
}
@immutable
......@@ -36,12 +36,12 @@ class Section {
this.rightColor,
this.details,
});
final String title;
final String backgroundAsset;
final String backgroundAssetPackage;
final Color leftColor;
final Color rightColor;
final List<SectionDetail> details;
final String? title;
final String? backgroundAsset;
final String? backgroundAssetPackage;
final Color? leftColor;
final Color? rightColor;
final List<SectionDetail>? details;
@override
bool operator==(Object other) {
......
......@@ -10,9 +10,8 @@ const double kSectionIndicatorWidth = 32.0;
// The card for a single section. Displays the section's gradient and background image.
class SectionCard extends StatelessWidget {
const SectionCard({ Key key, @required this.section })
: assert(section != null),
super(key: key);
const SectionCard({ Key? key, required this.section })
: super(key: key);
final Section section;
......@@ -27,13 +26,13 @@ class SectionCard extends StatelessWidget {
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: <Color>[
section.leftColor,
section.rightColor,
section.leftColor!,
section.rightColor!,
],
),
),
child: Image.asset(
section.backgroundAsset,
section.backgroundAsset!,
package: section.backgroundAssetPackage,
color: const Color.fromRGBO(255, 255, 255, 0.075),
colorBlendMode: BlendMode.modulate,
......@@ -48,13 +47,11 @@ class SectionCard extends StatelessWidget {
// offset a little. It's supposed to look sort-of 3D.
class SectionTitle extends StatelessWidget {
const SectionTitle({
Key key,
@required this.section,
@required this.scale,
@required this.opacity,
}) : assert(section != null),
assert(scale != null),
assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
Key? key,
required this.section,
required this.scale,
required this.opacity,
}) : assert(opacity >= 0.0 && opacity <= 1.0),
super(key: key);
final Section section;
......@@ -86,9 +83,9 @@ class SectionTitle extends StatelessWidget {
children: <Widget>[
Positioned(
top: 4.0,
child: Text(section.title, style: sectionTitleShadowStyle),
child: Text(section.title!, style: sectionTitleShadowStyle),
),
Text(section.title, style: sectionTitleStyle),
Text(section.title!, style: sectionTitleStyle),
],
),
),
......@@ -99,7 +96,7 @@ class SectionTitle extends StatelessWidget {
// Small horizontal bar that indicates the selected section.
class SectionIndicator extends StatelessWidget {
const SectionIndicator({ Key key, this.opacity = 1.0 }) : super(key: key);
const SectionIndicator({ Key? key, this.opacity = 1.0 }) : super(key: key);
final double opacity;
......@@ -117,8 +114,8 @@ class SectionIndicator extends StatelessWidget {
// Display a single SectionDetail.
class SectionDetailView extends StatelessWidget {
SectionDetailView({ Key key, @required this.detail })
: assert(detail != null && detail.imageAsset != null),
SectionDetailView({ Key? key, required this.detail })
: assert(detail.imageAsset != null),
assert((detail.imageAsset ?? detail.title) != null),
super(key: key);
......@@ -131,7 +128,7 @@ class SectionDetailView extends StatelessWidget {
borderRadius: BorderRadius.circular(6.0),
image: DecorationImage(
image: AssetImage(
detail.imageAsset,
detail.imageAsset!,
package: detail.imageAssetPackage,
),
fit: BoxFit.cover,
......@@ -153,8 +150,8 @@ class SectionDetailView extends StatelessWidget {
);
} else {
item = ListTile(
title: Text(detail.title),
subtitle: Text(detail.subtitle),
title: Text(detail.title!),
subtitle: Text(detail.subtitle!),
leading: SizedBox(width: 32.0, height: 32.0, child: image),
);
}
......
......@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'animation/home.dart';
class AnimationDemo extends StatelessWidget {
const AnimationDemo({Key key}) : super(key: key);
const AnimationDemo({Key? key}) : super(key: key);
static const String routeName = '/animation';
......
......@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'logic.dart';
class Calculator extends StatefulWidget {
const Calculator({Key key}) : super(key: key);
const Calculator({Key? key}) : super(key: key);
@override
_CalculatorState createState() => _CalculatorState();
......@@ -43,7 +43,7 @@ class _CalculatorState extends State<Calculator> {
}
void handleNumberTap(int n) {
final CalcExpression expression = _expression.appendDigit(n);
final CalcExpression? expression = _expression.appendDigit(n);
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -52,7 +52,7 @@ class _CalculatorState extends State<Calculator> {
}
void handlePointTap() {
final CalcExpression expression = _expression.appendPoint();
final CalcExpression? expression = _expression.appendPoint();
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -61,7 +61,7 @@ class _CalculatorState extends State<Calculator> {
}
void handlePlusTap() {
final CalcExpression expression = _expression.appendOperation(Operation.Addition);
final CalcExpression? expression = _expression.appendOperation(Operation.Addition);
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -70,7 +70,7 @@ class _CalculatorState extends State<Calculator> {
}
void handleMinusTap() {
final CalcExpression expression = _expression.appendMinus();
final CalcExpression? expression = _expression.appendMinus();
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -79,7 +79,7 @@ class _CalculatorState extends State<Calculator> {
}
void handleMultTap() {
final CalcExpression expression = _expression.appendOperation(Operation.Multiplication);
final CalcExpression? expression = _expression.appendOperation(Operation.Multiplication);
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -88,7 +88,7 @@ class _CalculatorState extends State<Calculator> {
}
void handleDivTap() {
final CalcExpression expression = _expression.appendOperation(Operation.Division);
final CalcExpression? expression = _expression.appendOperation(Operation.Division);
if (expression != null) {
setState(() {
pushExpression(expression);
......@@ -97,7 +97,7 @@ class _CalculatorState extends State<Calculator> {
}
void handleEqualsTap() {
final CalcExpression resultExpression = _expression.computeResult();
final CalcExpression? resultExpression = _expression.computeResult();
if (resultExpression != null) {
setState(() {
setResult(resultExpression);
......@@ -140,13 +140,13 @@ class _CalculatorState extends State<Calculator> {
class CalcDisplay extends StatelessWidget {
const CalcDisplay({ this.content });
final String content;
final String? content;
@override
Widget build(BuildContext context) {
return Center(
child: Text(
content,
content!,
style: const TextStyle(fontSize: 24.0),
),
);
......@@ -156,7 +156,7 @@ class CalcDisplay extends StatelessWidget {
class KeyPad extends StatelessWidget {
const KeyPad({ this.calcState });
final _CalculatorState calcState;
final _CalculatorState? calcState;
@override
Widget build(BuildContext context) {
......@@ -193,9 +193,9 @@ class KeyPad extends StatelessWidget {
NumberKey(3, calcState),
]),
KeyRow(<Widget>[
CalcKey('.', calcState.handlePointTap),
CalcKey('.', calcState!.handlePointTap),
NumberKey(0, calcState),
CalcKey('=', calcState.handleEqualsTap),
CalcKey('=', calcState!.handleEqualsTap),
]),
],
),
......@@ -205,11 +205,11 @@ class KeyPad extends StatelessWidget {
color: themeData.backgroundColor,
child: Column(
children: <Widget>[
CalcKey('\u232B', calcState.handleDelTap),
CalcKey('\u00F7', calcState.handleDivTap),
CalcKey('\u00D7', calcState.handleMultTap),
CalcKey('-', calcState.handleMinusTap),
CalcKey('+', calcState.handlePlusTap),
CalcKey('\u232B', calcState!.handleDelTap),
CalcKey('\u00F7', calcState!.handleDivTap),
CalcKey('\u00D7', calcState!.handleMultTap),
CalcKey('-', calcState!.handleMinusTap),
CalcKey('+', calcState!.handlePlusTap),
],
),
),
......@@ -263,8 +263,8 @@ class CalcKey extends StatelessWidget {
}
class NumberKey extends CalcKey {
NumberKey(int value, _CalculatorState calcState)
NumberKey(int value, _CalculatorState? calcState)
: super('$value', () {
calcState.handleNumberTap(value);
calcState!.handleNumberTap(value);
});
}
......@@ -9,10 +9,10 @@
class ExpressionToken {
ExpressionToken(this.stringRep);
final String stringRep;
final String? stringRep;
@override
String toString() => stringRep;
String toString() => stringRep!;
}
/// A token that represents a number.
......@@ -71,7 +71,7 @@ class OperationToken extends ExpressionToken {
Operation operation;
static String opString(Operation operation) {
static String? opString(Operation operation) {
switch (operation) {
case Operation.Addition:
return ' + ';
......@@ -82,8 +82,6 @@ class OperationToken extends ExpressionToken {
case Operation.Division:
return ' \u00F7 ';
}
assert(operation != null);
return null;
}
}
......@@ -124,13 +122,13 @@ class CalcExpression {
: this(<ExpressionToken>[], ExpressionState.Start);
CalcExpression.result(FloatToken result)
: _list = <ExpressionToken>[],
: _list = <ExpressionToken?>[],
state = ExpressionState.Result {
_list.add(result);
}
/// The tokens comprising the expression.
final List<ExpressionToken> _list;
final List<ExpressionToken?> _list;
/// The state of the expression.
final ExpressionState state;
......@@ -146,10 +144,10 @@ class CalcExpression {
/// Append a digit to the current expression and return a new expression
/// representing the result. Returns null to indicate that it is not legal
/// to append a digit in the current state.
CalcExpression appendDigit(int digit) {
CalcExpression? appendDigit(int digit) {
ExpressionState newState = ExpressionState.Number;
ExpressionToken newToken;
final List<ExpressionToken> outList = _list.toList();
ExpressionToken? newToken;
final List<ExpressionToken?> outList = _list.toList();
switch (state) {
case ExpressionState.Start:
// Start a new number with digit.
......@@ -161,12 +159,12 @@ class CalcExpression {
newToken = IntToken('-$digit');
break;
case ExpressionState.Number:
final ExpressionToken last = outList.removeLast();
final ExpressionToken last = outList.removeLast()!;
newToken = IntToken('${last.stringRep}$digit');
break;
case ExpressionState.Point:
case ExpressionState.NumberWithPoint:
final ExpressionToken last = outList.removeLast();
final ExpressionToken last = outList.removeLast()!;
newState = ExpressionState.NumberWithPoint;
newToken = FloatToken('${last.stringRep}$digit');
break;
......@@ -181,17 +179,17 @@ class CalcExpression {
/// Append a point to the current expression and return a new expression
/// representing the result. Returns null to indicate that it is not legal
/// to append a point in the current state.
CalcExpression appendPoint() {
ExpressionToken newToken;
final List<ExpressionToken> outList = _list.toList();
CalcExpression? appendPoint() {
ExpressionToken? newToken;
final List<ExpressionToken?> outList = _list.toList();
switch (state) {
case ExpressionState.Start:
newToken = FloatToken('.');
break;
case ExpressionState.LeadingNeg:
case ExpressionState.Number:
final ExpressionToken last = outList.removeLast();
newToken = FloatToken(last.stringRep + '.');
final ExpressionToken last = outList.removeLast()!;
newToken = FloatToken(last.stringRep! + '.');
break;
case ExpressionState.Point:
case ExpressionState.NumberWithPoint:
......@@ -206,7 +204,7 @@ class CalcExpression {
/// Append an operation symbol to the current expression and return a new
/// expression representing the result. Returns null to indicate that it is not
/// legal to append an operation symbol in the current state.
CalcExpression appendOperation(Operation op) {
CalcExpression? appendOperation(Operation op) {
switch (state) {
case ExpressionState.Start:
case ExpressionState.LeadingNeg:
......@@ -218,7 +216,7 @@ class CalcExpression {
case ExpressionState.Result:
break;
}
final List<ExpressionToken> outList = _list.toList();
final List<ExpressionToken?> outList = _list.toList();
outList.add(OperationToken(op));
return CalcExpression(outList, ExpressionState.Start);
}
......@@ -226,7 +224,7 @@ class CalcExpression {
/// Append a leading minus sign to the current expression and return a new
/// expression representing the result. Returns null to indicate that it is not
/// legal to append a leading minus sign in the current state.
CalcExpression appendLeadingNeg() {
CalcExpression? appendLeadingNeg() {
switch (state) {
case ExpressionState.Start:
break;
......@@ -238,7 +236,7 @@ class CalcExpression {
// Cannot enter leading neg now.
return null;
}
final List<ExpressionToken> outList = _list.toList();
final List<ExpressionToken?> outList = _list.toList();
outList.add(LeadingNegToken());
return CalcExpression(outList, ExpressionState.LeadingNeg);
}
......@@ -248,7 +246,7 @@ class CalcExpression {
/// to append a minus sign in the current state. Depending on the current
/// state the minus sign will be interpreted as either a leading negative
/// sign or a subtraction operation.
CalcExpression appendMinus() {
CalcExpression? appendMinus() {
switch (state) {
case ExpressionState.Start:
return appendLeadingNeg();
......@@ -266,7 +264,7 @@ class CalcExpression {
/// Computes the result of the current expression and returns a new
/// ResultExpression containing the result. Returns null to indicate that
/// it is not legal to compute a result in the current state.
CalcExpression computeResult() {
CalcExpression? computeResult() {
switch (state) {
case ExpressionState.Start:
case ExpressionState.LeadingNeg:
......@@ -281,13 +279,13 @@ class CalcExpression {
// We make a copy of _list because CalcExpressions are supposed to
// be immutable.
final List<ExpressionToken> list = _list.toList();
final List<ExpressionToken?> list = _list.toList();
// We obey order-of-operations by computing the sum of the 'terms',
// where a "term" is defined to be a sequence of numbers separated by
// multiplication or division symbols.
num currentTermValue = removeNextTerm(list);
while (list.isNotEmpty) {
final OperationToken opToken = list.removeAt(0) as OperationToken;
final OperationToken opToken = list.removeAt(0)! as OperationToken;
final num nextTermValue = removeNextTerm(list);
switch (opToken.operation) {
case Operation.Addition:
......@@ -311,13 +309,13 @@ class CalcExpression {
/// Removes the next "term" from `list` and returns its numeric value.
/// A "term" is a sequence of number tokens separated by multiplication
/// and division symbols.
static num removeNextTerm(List<ExpressionToken> list) {
assert(list != null && list.isNotEmpty);
final NumberToken firstNumToken = list.removeAt(0) as NumberToken;
static num removeNextTerm(List<ExpressionToken?> list) {
assert(list.isNotEmpty);
final NumberToken firstNumToken = list.removeAt(0)! as NumberToken;
num currentValue = firstNumToken.number;
while (list.isNotEmpty) {
bool isDivision = false;
final OperationToken nextOpToken = list.first as OperationToken;
final OperationToken nextOpToken = list.first! as OperationToken;
switch (nextOpToken.operation) {
case Operation.Addition:
case Operation.Subtraction:
......@@ -331,7 +329,7 @@ class CalcExpression {
// Remove the operation token.
list.removeAt(0);
// Remove the next number token.
final NumberToken nextNumToken = list.removeAt(0) as NumberToken;
final NumberToken nextNumToken = list.removeAt(0)! as NumberToken;
final num nextNumber = nextNumToken.number;
if (isDivision)
currentValue /= nextNumber;
......
......@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'calculator/home.dart';
class CalculatorDemo extends StatelessWidget {
const CalculatorDemo({Key key}) : super(key: key);
const CalculatorDemo({Key? key}) : super(key: key);
static const String routeName = '/calculator';
......
......@@ -9,12 +9,12 @@ const double kColorItemHeight = 48.0;
class Palette {
Palette({ this.name, this.primary, this.accent, this.threshold = 900});
final String name;
final MaterialColor primary;
final MaterialAccentColor accent;
final String? name;
final MaterialColor? primary;
final MaterialAccentColor? accent;
final int threshold; // titles for indices > threshold are white, otherwise black
bool get isValid => name != null && primary != null && threshold != null;
bool get isValid => name != null && primary != null;
}
final List<Palette> allPalettes = <Palette>[
......@@ -42,14 +42,11 @@ final List<Palette> allPalettes = <Palette>[
class ColorItem extends StatelessWidget {
const ColorItem({
Key key,
@required this.index,
@required this.color,
Key? key,
required this.index,
required this.color,
this.prefix = '',
}) : assert(index != null),
assert(color != null),
assert(prefix != null),
super(key: key);
}) : super(key: key);
final int index;
final Color color;
......@@ -84,9 +81,9 @@ class ColorItem extends StatelessWidget {
class PaletteTabView extends StatelessWidget {
PaletteTabView({
Key key,
@required this.colors,
}) : assert(colors != null && colors.isValid),
Key? key,
required this.colors,
}) : assert(colors.isValid),
super(key: key);
final Palette colors;
......@@ -97,8 +94,8 @@ class PaletteTabView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final TextTheme textTheme = Theme.of(context).textTheme;
final TextStyle whiteTextStyle = textTheme.bodyText2.copyWith(color: Colors.white);
final TextStyle blackTextStyle = textTheme.bodyText2.copyWith(color: Colors.black);
final TextStyle whiteTextStyle = textTheme.bodyText2!.copyWith(color: Colors.white);
final TextStyle blackTextStyle = textTheme.bodyText2!.copyWith(color: Colors.black);
return Scrollbar(
child: ListView(
itemExtent: kColorItemHeight,
......@@ -106,14 +103,14 @@ class PaletteTabView extends StatelessWidget {
...primaryKeys.map<Widget>((int index) {
return DefaultTextStyle(
style: index > colors.threshold ? whiteTextStyle : blackTextStyle,
child: ColorItem(index: index, color: colors.primary[index]),
child: ColorItem(index: index, color: colors.primary![index]!),
);
}),
if (colors.accent != null)
...accentKeys.map<Widget>((int index) {
return DefaultTextStyle(
style: index > colors.threshold ? whiteTextStyle : blackTextStyle,
child: ColorItem(index: index, color: colors.accent[index], prefix: 'A'),
child: ColorItem(index: index, color: colors.accent![index]!, prefix: 'A'),
);
}),
],
......
......@@ -6,10 +6,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class _ContactCategory extends StatelessWidget {
const _ContactCategory({ Key key, this.icon, this.children }) : super(key: key);
const _ContactCategory({ Key? key, this.icon, this.children }) : super(key: key);
final IconData icon;
final List<Widget> children;
final IconData? icon;
final List<Widget>? children;
@override
Widget build(BuildContext context) {
......@@ -20,7 +20,7 @@ class _ContactCategory extends StatelessWidget {
border: Border(bottom: BorderSide(color: themeData.dividerColor))
),
child: DefaultTextStyle(
style: Theme.of(context).textTheme.subtitle1,
style: Theme.of(context).textTheme.subtitle1!,
child: SafeArea(
top: false,
bottom: false,
......@@ -32,7 +32,7 @@ class _ContactCategory extends StatelessWidget {
width: 72.0,
child: Icon(icon, color: themeData.primaryColor),
),
Expanded(child: Column(children: children)),
Expanded(child: Column(children: children!)),
],
),
),
......@@ -42,14 +42,14 @@ class _ContactCategory extends StatelessWidget {
}
class _ContactItem extends StatelessWidget {
const _ContactItem({ Key key, this.icon, this.lines, this.tooltip, this.onPressed })
const _ContactItem({ Key? key, this.icon, required this.lines, this.tooltip, this.onPressed })
: assert(lines.length > 1),
super(key: key);
final IconData icon;
final IconData? icon;
final List<String> lines;
final String tooltip;
final VoidCallback onPressed;
final String? tooltip;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
......
......@@ -14,24 +14,24 @@ class CupertinoAlertDemo extends StatefulWidget {
}
class _CupertinoAlertDemoState extends State<CupertinoAlertDemo> {
String lastSelectedValue;
String? lastSelectedValue;
void showDemoDialog({BuildContext context, Widget child}) {
void showDemoDialog({required BuildContext context, Widget? child}) {
showCupertinoDialog<String>(
context: context,
builder: (BuildContext context) => child,
).then((String value) {
builder: (BuildContext context) => child!,
).then((String? value) {
if (value != null) {
setState(() { lastSelectedValue = value; });
}
});
}
void showDemoActionSheet({BuildContext context, Widget child}) {
void showDemoActionSheet({required BuildContext context, Widget? child}) {
showCupertinoModalPopup<String>(
context: context,
builder: (BuildContext context) => child,
).then((String value) {
builder: (BuildContext context) => child!,
).then((String? value) {
if (value != null) {
setState(() { lastSelectedValue = value; });
}
......@@ -196,10 +196,10 @@ class _CupertinoAlertDemoState extends State<CupertinoAlertDemo> {
}
class CupertinoDessertDialog extends StatelessWidget {
const CupertinoDessertDialog({Key key, this.title, this.content}) : super(key: key);
const CupertinoDessertDialog({Key? key, this.title, this.content}) : super(key: key);
final Widget title;
final Widget content;
final Widget? title;
final Widget? content;
@override
Widget build(BuildContext context) {
......
......@@ -44,7 +44,7 @@ class CupertinoNavigationDemo extends StatelessWidget {
final List<Color> colorItems;
final List<String> colorNameItems;
final int randomSeed;
final int? randomSeed;
@override
Widget build(BuildContext context) {
......@@ -71,7 +71,6 @@ class CupertinoNavigationDemo extends StatelessWidget {
],
),
tabBuilder: (BuildContext context, int index) {
assert(index >= 0 && index <= 2);
switch (index) {
case 0:
return CupertinoTabView(
......@@ -84,21 +83,19 @@ class CupertinoNavigationDemo extends StatelessWidget {
},
defaultTitle: 'Colors',
);
break;
case 1:
return CupertinoTabView(
builder: (BuildContext context) => CupertinoDemoTab2(),
defaultTitle: 'Support Chat',
);
break;
case 2:
return CupertinoTabView(
builder: (BuildContext context) => CupertinoDemoTab3(),
defaultTitle: 'Account',
);
break;
}
return null;
assert(false);
return const CupertinoTabView();
},
),
),
......@@ -120,7 +117,7 @@ class ExitButton extends StatelessWidget {
),
onPressed: () {
// The demo is on the root navigator.
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context, rootNavigator: true)!.pop();
},
);
}
......@@ -142,9 +139,9 @@ class CupertinoDemoTab1 extends StatelessWidget {
this.randomSeed,
});
final List<Color> colorItems;
final List<String> colorNameItems;
final int randomSeed;
final List<Color>? colorItems;
final List<String>? colorNameItems;
final int? randomSeed;
@override
Widget build(BuildContext context) {
......@@ -170,8 +167,8 @@ class CupertinoDemoTab1 extends StatelessWidget {
return Tab1RowItem(
index: index,
lastItem: index == _kChildCount - 1,
color: colorItems[index],
colorName: colorNameItems[index],
color: colorItems![index],
colorName: colorNameItems![index],
randomSeed: randomSeed,
);
},
......@@ -194,18 +191,18 @@ class Tab1RowItem extends StatelessWidget {
this.randomSeed,
});
final int index;
final bool lastItem;
final Color color;
final String colorName;
final int randomSeed;
final int? index;
final bool? lastItem;
final Color? color;
final String? colorName;
final int? randomSeed;
@override
Widget build(BuildContext context) {
final Widget row = GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).push(CupertinoPageRoute<void>(
Navigator.of(context)!.push(CupertinoPageRoute<void>(
title: colorName,
builder: (BuildContext context) => Tab1ItemPage(
color: color,
......@@ -238,7 +235,7 @@ class Tab1RowItem extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(colorName),
Text(colorName!),
const Padding(padding: EdgeInsets.only(top: 8.0)),
Text(
'Buy this cool color',
......@@ -273,7 +270,7 @@ class Tab1RowItem extends StatelessWidget {
),
);
if (lastItem) {
if (lastItem!) {
return row;
}
......@@ -292,10 +289,10 @@ class Tab1RowItem extends StatelessWidget {
class Tab1ItemPage extends StatefulWidget {
const Tab1ItemPage({this.color, this.colorName, this.index, this.randomSeed});
final Color color;
final String colorName;
final int index;
final int randomSeed;
final Color? color;
final String? colorName;
final int? index;
final int? randomSeed;
@override
State<StatefulWidget> createState() => Tab1ItemPageState();
......@@ -309,14 +306,14 @@ class Tab1ItemPageState extends State<Tab1ItemPage> {
final math.Random random = math.Random(widget.randomSeed);
return Color.fromARGB(
255,
(widget.color.red + random.nextInt(100) - 50).clamp(0, 255) as int,
(widget.color.green + random.nextInt(100) - 50).clamp(0, 255) as int,
(widget.color.blue + random.nextInt(100) - 50).clamp(0, 255) as int,
(widget.color!.red + random.nextInt(100) - 50).clamp(0, 255),
(widget.color!.green + random.nextInt(100) - 50).clamp(0, 255),
(widget.color!.blue + random.nextInt(100) - 50).clamp(0, 255),
);
});
}
List<Color> relatedColors;
late List<Color> relatedColors;
@override
Widget build(BuildContext context) {
......@@ -350,7 +347,7 @@ class Tab1ItemPageState extends State<Tab1ItemPage> {
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
widget.colorName,
widget.colorName!,
style: const TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
const Padding(padding: EdgeInsets.only(top: 6.0)),
......@@ -594,13 +591,13 @@ enum Tab2ConversationBubbleColor {
class Tab2ConversationBubble extends StatelessWidget {
const Tab2ConversationBubble({this.text, this.color});
final String text;
final Tab2ConversationBubbleColor color;
final String? text;
final Tab2ConversationBubbleColor? color;
@override
Widget build(BuildContext context) {
Color backgroundColor;
Color foregroundColor;
Color? backgroundColor;
Color? foregroundColor;
switch (color) {
case Tab2ConversationBubbleColor.gray:
......@@ -611,6 +608,8 @@ class Tab2ConversationBubble extends StatelessWidget {
backgroundColor = CupertinoTheme.of(context).primaryColor;
foregroundColor = CupertinoColors.white;
break;
default:
break;
}
return Container(
......@@ -621,7 +620,7 @@ class Tab2ConversationBubble extends StatelessWidget {
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
padding: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 10.0),
child: Text(
text,
text!,
style: TextStyle(
color: foregroundColor,
letterSpacing: -0.4,
......@@ -636,8 +635,8 @@ class Tab2ConversationBubble extends StatelessWidget {
class Tab2ConversationAvatar extends StatelessWidget {
const Tab2ConversationAvatar({this.text, this.color});
final String text;
final Color color;
final String? text;
final Color? color;
@override
Widget build(BuildContext context) {
......@@ -648,20 +647,20 @@ class Tab2ConversationAvatar extends StatelessWidget {
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
colors: <Color>[
color,
color!,
Color.fromARGB(
color.alpha,
(color.red - 60).clamp(0, 255) as int,
(color.green - 60).clamp(0, 255) as int,
(color.blue - 60).clamp(0, 255) as int,
color!.alpha,
(color!.red - 60).clamp(0, 255),
(color!.green - 60).clamp(0, 255),
(color!.blue - 60).clamp(0, 255),
),
],
]
),
),
margin: const EdgeInsets.only(left: 8.0, bottom: 8.0),
padding: const EdgeInsets.all(12.0),
child: Text(
text,
text!,
style: const TextStyle(
color: CupertinoColors.white,
fontSize: 13.0,
......@@ -675,8 +674,8 @@ class Tab2ConversationAvatar extends StatelessWidget {
class Tab2ConversationRow extends StatelessWidget {
const Tab2ConversationRow({this.avatar, this.text});
final Tab2ConversationAvatar avatar;
final String text;
final Tab2ConversationAvatar? avatar;
final String? text;
@override
Widget build(BuildContext context) {
......@@ -687,7 +686,8 @@ class Tab2ConversationRow extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: isSelf ? CrossAxisAlignment.center : CrossAxisAlignment.end,
children: <Widget>[
if (avatar != null) avatar,
if (avatar != null)
avatar!,
CupertinoUserInterfaceLevel(
data: CupertinoUserInterfaceLevelData.elevated,
child: Tab2ConversationBubble(
......@@ -752,7 +752,7 @@ class CupertinoDemoTab3 extends StatelessWidget {
const Padding(padding: EdgeInsets.only(top: 32.0)),
GestureDetector(
onTap: () {
Navigator.of(context, rootNavigator: true).push(
Navigator.of(context, rootNavigator: true)!.push(
CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => Tab3Dialog(),
......@@ -800,7 +800,7 @@ class Tab3Dialog extends StatelessWidget {
child: const Text('Cancel'),
padding: EdgeInsets.zero,
onPressed: () {
Navigator.of(context).pop(false);
Navigator.of(context)!.pop(false);
},
),
),
......
......@@ -20,10 +20,9 @@ class CupertinoPickerDemo extends StatefulWidget {
class _BottomPicker extends StatelessWidget {
const _BottomPicker({
Key key,
@required this.child,
}) : assert(child != null),
super(key: key);
Key? key,
required this.child,
}) : super(key: key);
final Widget child;
......@@ -53,10 +52,9 @@ class _BottomPicker extends StatelessWidget {
class _Menu extends StatelessWidget {
const _Menu({
Key key,
@required this.children,
}) : assert(children != null),
super(key: key);
Key? key,
required this.children,
}) : super(key: key);
final List<Widget> children;
......
......@@ -16,7 +16,7 @@ class CupertinoRefreshControlDemo extends StatefulWidget {
}
class _CupertinoRefreshControlDemoState extends State<CupertinoRefreshControlDemo> {
List<List<String>> randomizedContacts;
late List<List<String>> randomizedContacts;
@override
void initState() {
......@@ -64,7 +64,7 @@ class _CupertinoRefreshControlDemoState extends State<CupertinoRefreshControlDem
CupertinoSliverRefreshControl(
onRefresh: () {
return Future<void>.delayed(const Duration(seconds: 2))
..then<void>((_) {
..then((_) {
if (mounted) {
setState(() => repopulateList());
}
......@@ -149,10 +149,10 @@ class _ListItem extends StatelessWidget {
this.called,
});
final String name;
final String place;
final String date;
final bool called;
final String? name;
final String? place;
final String? date;
final bool? called;
@override
Widget build(BuildContext context) {
......@@ -164,7 +164,7 @@ class _ListItem extends StatelessWidget {
children: <Widget>[
Container(
width: 38.0,
child: called
child: called!
? Align(
alignment: Alignment.topCenter,
child: Icon(
......@@ -191,7 +191,7 @@ class _ListItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
name,
name!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
......@@ -200,7 +200,7 @@ class _ListItem extends StatelessWidget {
),
),
Text(
place,
place!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
......@@ -213,7 +213,7 @@ class _ListItem extends StatelessWidget {
),
),
Text(
date,
date!,
style: TextStyle(
color: CupertinoColors.inactiveGray.resolveFrom(context),
fontSize: 15.0,
......
......@@ -43,9 +43,9 @@ class _CupertinoSegmentedControlDemoState extends State<CupertinoSegmentedContro
),
};
int currentSegment = 0;
int? currentSegment = 0;
void onValueChanged(int newValue) {
void onValueChanged(int? newValue) {
setState(() {
currentSegment = newValue;
});
......@@ -126,7 +126,7 @@ class _CupertinoSegmentedControlDemoState extends State<CupertinoSegmentedContro
),
],
),
child: icons[currentSegment],
child: icons[currentSegment!],
);
},
),
......
......@@ -14,8 +14,8 @@ class CupertinoTextFieldDemo extends StatefulWidget {
}
class _CupertinoTextFieldDemoState extends State<CupertinoTextFieldDemo> {
TextEditingController _chatTextController;
TextEditingController _locationTextController;
TextEditingController? _chatTextController;
TextEditingController? _locationTextController;
@override
void initState() {
......@@ -49,12 +49,12 @@ class _CupertinoTextFieldDemoState extends State<CupertinoTextFieldDemo> {
color: CupertinoColors.activeGreen,
),
padding: const EdgeInsets.only(bottom: 4),
onPressed: ()=> setState(()=> _chatTextController.clear()),
onPressed: ()=> setState(()=> _chatTextController!.clear()),
),
),
autofocus: true,
suffixMode: OverlayVisibilityMode.editing,
onSubmitted: (String text)=> setState(()=> _chatTextController.clear()),
onSubmitted: (String text)=> setState(()=> _chatTextController!.clear()),
);
}
......
......@@ -33,7 +33,7 @@ class FortnightlyDemo extends StatelessWidget {
class ShortAppBar extends StatelessWidget {
const ShortAppBar({ this.onBackPressed });
final VoidCallback onBackPressed;
final VoidCallback? onBackPressed;
@override
Widget build(BuildContext context) {
......@@ -118,7 +118,7 @@ over water meant for the whole central valley of California? The story will shoc
Text(
' ¬ ',
// TODO(larche): Replace textTheme.headline2.color with a ColorScheme value when known.
style: textTheme.overline.apply(color: textTheme.headline2.color),
style: textTheme.overline!.apply(color: textTheme.headline2!.color),
),
Text(
'CULTURE',
......@@ -196,7 +196,7 @@ TextTheme _buildTextTheme(TextTheme base) {
theme = theme.apply(displayColor: Colors.black);
theme = theme.copyWith(
headline4: base.headline4.copyWith(
headline4: base.headline4!.copyWith(
fontFamily: 'Merriweather',
fontStyle: FontStyle.italic,
fontSize: 28,
......@@ -204,21 +204,21 @@ TextTheme _buildTextTheme(TextTheme base) {
color: Colors.black,
height: .88,
),
headline2: base.headline2.copyWith(
headline2: base.headline2!.copyWith(
fontFamily: 'LibreFranklin',
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.black.withAlpha(153),
),
headline5: base.headline5.copyWith(fontWeight: FontWeight.w500),
bodyText2: base.bodyText2.copyWith(
headline5: base.headline5!.copyWith(fontWeight: FontWeight.w500),
bodyText2: base.bodyText2!.copyWith(
fontFamily: 'Merriweather',
fontSize: 14,
fontWeight: FontWeight.w300,
color: const Color(0xFF666666),
height: 1.11,
),
bodyText1: base.bodyText1.copyWith(
bodyText1: base.bodyText1!.copyWith(
fontFamily: 'Merriweather',
fontSize: 16,
fontWeight: FontWeight.w300,
......
......@@ -12,8 +12,8 @@ import 'package:flutter/material.dart';
class Category {
const Category({ this.title, this.assets });
final String title;
final List<String> assets;
final String? title;
final List<String>? assets;
@override
String toString() => '$runtimeType("$title")';
}
......@@ -95,21 +95,21 @@ const List<Category> allCategories = <Category>[
];
class CategoryView extends StatelessWidget {
const CategoryView({ Key key, this.category }) : super(key: key);
const CategoryView({ Key? key, this.category }) : super(key: key);
final Category category;
final Category? category;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return Scrollbar(
child: ListView(
key: PageStorageKey<Category>(category),
key: PageStorageKey<Category?>(category),
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 64.0,
),
children: category.assets.map<Widget>((String asset) {
children: category!.assets!.map<Widget>((String asset) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
......@@ -149,7 +149,7 @@ class CategoryView extends StatelessWidget {
// BackdropDemo.
class BackdropPanel extends StatelessWidget {
const BackdropPanel({
Key key,
Key? key,
this.onTap,
this.onVerticalDragUpdate,
this.onVerticalDragEnd,
......@@ -157,11 +157,11 @@ class BackdropPanel extends StatelessWidget {
this.child,
}) : super(key: key);
final VoidCallback onTap;
final GestureDragUpdateCallback onVerticalDragUpdate;
final GestureDragEndCallback onVerticalDragEnd;
final Widget title;
final Widget child;
final VoidCallback? onTap;
final GestureDragUpdateCallback? onVerticalDragUpdate;
final GestureDragEndCallback? onVerticalDragEnd;
final Widget? title;
final Widget? child;
@override
Widget build(BuildContext context) {
......@@ -185,7 +185,7 @@ class BackdropPanel extends StatelessWidget {
padding: const EdgeInsetsDirectional.only(start: 16.0),
alignment: AlignmentDirectional.centerStart,
child: DefaultTextStyle(
style: theme.textTheme.subtitle1,
style: theme.textTheme.subtitle1!,
child: Tooltip(
message: 'Tap to dismiss',
child: title,
......@@ -194,7 +194,7 @@ class BackdropPanel extends StatelessWidget {
),
),
const Divider(height: 1.0),
Expanded(child: child),
Expanded(child: child!),
],
),
);
......@@ -204,15 +204,15 @@ class BackdropPanel extends StatelessWidget {
// Cross fades between 'Select a Category' and 'Asset Viewer'.
class BackdropTitle extends AnimatedWidget {
const BackdropTitle({
Key key,
Animation<double> listenable,
Key? key,
required Animation<double> listenable,
}) : super(key: key, listenable: listenable);
@override
Widget build(BuildContext context) {
final Animation<double> animation = listenable as Animation<double>;
return DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.headline6,
style: Theme.of(context).primaryTextTheme.headline6!,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: Stack(
......@@ -247,7 +247,7 @@ class BackdropDemo extends StatefulWidget {
class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderStateMixin {
final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');
AnimationController _controller;
late AnimationController _controller;
Category _category = allCategories[0];
@override
......@@ -283,7 +283,7 @@ class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderSt
}
double get _backdropHeight {
final RenderBox renderBox = _backdropKey.currentContext.findRenderObject() as RenderBox;
final RenderBox renderBox = _backdropKey.currentContext!.findRenderObject()! as RenderBox;
return renderBox.size.height;
}
......@@ -294,7 +294,7 @@ class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderSt
if (_controller.isAnimating || _controller.status == AnimationStatus.completed)
return;
_controller.value -= details.primaryDelta / (_backdropHeight ?? details.primaryDelta);
_controller.value -= details.primaryDelta! / _backdropHeight;
}
void _handleDragEnd(DragEndDetails details) {
......@@ -343,7 +343,7 @@ class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderSt
? Colors.white.withOpacity(0.25)
: Colors.transparent,
child: ListTile(
title: Text(category.title),
title: Text(category.title!),
selected: selected,
onTap: () {
_changeCategory(category);
......@@ -359,8 +359,8 @@ class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderSt
children: <Widget>[
ListTileTheme(
iconColor: theme.primaryIconTheme.color,
textColor: theme.primaryTextTheme.headline6.color.withOpacity(0.6),
selectedColor: theme.primaryTextTheme.headline6.color,
textColor: theme.primaryTextTheme.headline6!.color!.withOpacity(0.6),
selectedColor: theme.primaryTextTheme.headline6!.color,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
......@@ -375,7 +375,7 @@ class _BackdropDemoState extends State<BackdropDemo> with SingleTickerProviderSt
onTap: _toggleBackdropPanelVisibility,
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
title: Text(_category.title),
title: Text(_category.title!),
child: CategoryView(category: _category),
),
),
......
......@@ -13,7 +13,7 @@ enum BannerDemoAction {
}
class BannerDemo extends StatefulWidget {
const BannerDemo({ Key key }) : super(key: key);
const BannerDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/banner';
......
......@@ -92,7 +92,7 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
"When the Scaffold's floating action button location changes, "
'the floating action button animates to its new position. '
'The BottomAppBar adapts its shape appropriately.';
_scaffoldMessengerKey.currentState.showSnackBar(
_scaffoldMessengerKey.currentState!.showSnackBar(
const SnackBar(content: Text(text)),
);
}
......@@ -111,27 +111,27 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
_ChoiceValue<Widget> _fabShape = kCircularFab;
_ChoiceValue<bool> _showNotch = kShowNotchTrue;
_ChoiceValue<FloatingActionButtonLocation> _fabLocation = kFabEndDocked;
Color _babColor = kBabColors.first.color;
Color? _babColor = kBabColors.first.color;
void _onShowNotchChanged(_ChoiceValue<bool> value) {
void _onShowNotchChanged(_ChoiceValue<bool>? value) {
setState(() {
_showNotch = value;
_showNotch = value!;
});
}
void _onFabShapeChanged(_ChoiceValue<Widget> value) {
void _onFabShapeChanged(_ChoiceValue<Widget>? value) {
setState(() {
_fabShape = value;
_fabShape = value!;
});
}
void _onFabLocationChanged(_ChoiceValue<FloatingActionButtonLocation> value) {
void _onFabLocationChanged(_ChoiceValue<FloatingActionButtonLocation>? value) {
setState(() {
_fabLocation = value;
_fabLocation = value!;
});
}
void _onBabColorChanged(Color value) {
void _onBabColorChanged(Color? value) {
setState(() {
_babColor = value;
});
......@@ -201,8 +201,8 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
);
}
NotchedShape _selectNotch() {
if (!_showNotch.value)
NotchedShape? _selectNotch() {
if (!_showNotch.value!)
return null;
if (_fabShape == kCircularFab)
return const CircularNotchedRectangle();
......@@ -215,9 +215,9 @@ class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
class _ChoiceValue<T> {
const _ChoiceValue({ this.value, this.title, this.label });
final T value;
final String title;
final String label; // For the Semantics widget that contains title
final T? value;
final String? title;
final String? label; // For the Semantics widget that contains title
@override
String toString() => '$runtimeType("$title")';
......@@ -228,7 +228,7 @@ class _RadioItem<T> extends StatelessWidget {
final _ChoiceValue<T> value;
final _ChoiceValue<T> groupValue;
final ValueChanged<_ChoiceValue<T>> onChanged;
final ValueChanged<_ChoiceValue<T>?> onChanged;
@override
Widget build(BuildContext context) {
......@@ -256,7 +256,7 @@ class _RadioItem<T> extends StatelessWidget {
onChanged(value);
},
child: Text(
value.title,
value.title!,
style: theme.textTheme.subtitle1,
),
),
......@@ -272,7 +272,7 @@ class _RadioItem<T> extends StatelessWidget {
class _NamedColor {
const _NamedColor(this.color, this.name);
final Color color;
final Color? color;
final String name;
}
......@@ -280,8 +280,8 @@ class _ColorsItem extends StatelessWidget {
const _ColorsItem(this.colors, this.selectedColor, this.onChanged);
final List<_NamedColor> colors;
final Color selectedColor;
final ValueChanged<Color> onChanged;
final Color? selectedColor;
final ValueChanged<Color?> onChanged;
@override
Widget build(BuildContext context) {
......@@ -340,9 +340,9 @@ class _DemoBottomAppBar extends StatelessWidget {
this.shape,
});
final Color color;
final FloatingActionButtonLocation fabLocation;
final NotchedShape shape;
final Color? color;
final FloatingActionButtonLocation? fabLocation;
final NotchedShape? shape;
static final List<FloatingActionButtonLocation> kCenterLocations = <FloatingActionButtonLocation>[
FloatingActionButtonLocation.centerDocked,
......@@ -421,8 +421,8 @@ class _DiamondFab extends StatelessWidget {
this.onPressed,
});
final Widget child;
final VoidCallback onPressed;
final Widget? child;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
......@@ -436,7 +436,7 @@ class _DiamondFab extends StatelessWidget {
height: 56.0,
child: IconTheme.merge(
data: IconThemeData(color: Theme.of(context).accentIconTheme.color),
child: child,
child: child!,
),
),
),
......@@ -449,8 +449,8 @@ class _DiamondNotchedRectangle implements NotchedShape {
const _DiamondNotchedRectangle();
@override
Path getOuterPath(Rect host, Rect guest) {
if (!host.overlaps(guest))
Path getOuterPath(Rect host, Rect? guest) {
if (!host.overlaps(guest!))
return Path()..addRect(host);
assert(guest.width > 0.0);
......@@ -492,12 +492,12 @@ class _DiamondBorder extends ShapeBorder {
}
@override
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return getOuterPath(rect, textDirection: textDirection);
}
@override
Path getOuterPath(Rect rect, { TextDirection textDirection }) {
Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return Path()
..moveTo(rect.left + rect.width / 2.0, rect.top)
..lineTo(rect.right, rect.top + rect.height / 2.0)
......@@ -507,11 +507,11 @@ class _DiamondBorder extends ShapeBorder {
}
@override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { }
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) { }
// This border doesn't support scaling.
@override
ShapeBorder scale(double t) {
return null;
return this;
}
}
......@@ -8,11 +8,11 @@ import '../../gallery/demo.dart';
class NavigationIconView {
NavigationIconView({
Widget icon,
Widget activeIcon,
String title,
Color color,
TickerProvider vsync,
required Widget icon,
Widget? activeIcon,
String? title,
Color? color,
required TickerProvider vsync,
}) : _icon = icon,
_color = color,
_title = title,
......@@ -32,14 +32,14 @@ class NavigationIconView {
}
final Widget _icon;
final Color _color;
final String _title;
final Color? _color;
final String? _title;
final BottomNavigationBarItem item;
final AnimationController controller;
Animation<double> _animation;
late Animation<double> _animation;
FadeTransition transition(BottomNavigationBarType type, BuildContext context) {
Color iconColor;
Color? iconColor;
if (type == BottomNavigationBarType.shifting) {
iconColor = _color;
} else {
......@@ -79,8 +79,8 @@ class CustomIcon extends StatelessWidget {
final IconThemeData iconTheme = IconTheme.of(context);
return Container(
margin: const EdgeInsets.all(4.0),
width: iconTheme.size - 8.0,
height: iconTheme.size - 8.0,
width: iconTheme.size! - 8.0,
height: iconTheme.size! - 8.0,
color: iconTheme.color,
);
}
......@@ -92,10 +92,10 @@ class CustomInactiveIcon extends StatelessWidget {
final IconThemeData iconTheme = IconTheme.of(context);
return Container(
margin: const EdgeInsets.all(4.0),
width: iconTheme.size - 8.0,
height: iconTheme.size - 8.0,
width: iconTheme.size! - 8.0,
height: iconTheme.size! - 8.0,
decoration: BoxDecoration(
border: Border.all(color: iconTheme.color, width: 2.0),
border: Border.all(color: iconTheme.color!, width: 2.0),
),
);
}
......@@ -112,7 +112,7 @@ class _BottomNavigationDemoState extends State<BottomNavigationDemo>
with TickerProviderStateMixin {
int _currentIndex = 0;
BottomNavigationBarType _type = BottomNavigationBarType.shifting;
List<NavigationIconView> _navigationViews;
late List<NavigationIconView> _navigationViews;
@override
void initState() {
......
......@@ -53,7 +53,7 @@ class ButtonsDemo extends StatefulWidget {
}
class _ButtonsDemoState extends State<ButtonsDemo> {
OutlinedBorder _buttonShape;
OutlinedBorder? _buttonShape;
@override
Widget build(BuildContext context) {
......@@ -118,7 +118,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
);
}
Widget buildElevatedButton(OutlinedBorder shape) {
Widget buildElevatedButton(OutlinedBorder? shape) {
final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
return Align(
alignment: const Alignment(0.0, -0.2),
......@@ -156,7 +156,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
style: style,
icon: const Icon(Icons.add, size: 18.0),
label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 2'),
onPressed: null,
onPressed: () {},
),
],
),
......@@ -165,7 +165,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
);
}
Widget buildTextButton(OutlinedBorder shape) {
Widget buildTextButton(OutlinedBorder? shape) {
final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
return Align(
alignment: const Alignment(0.0, -0.2),
......@@ -203,7 +203,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
style: style,
icon: const Icon(Icons.add_circle_outline, size: 18.0),
label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 4'),
onPressed: null,
onPressed: () {},
),
],
),
......@@ -212,7 +212,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
);
}
Widget buildOutlinedButton(OutlinedBorder shape) {
Widget buildOutlinedButton(OutlinedBorder? shape) {
final ButtonStyle style = ElevatedButton.styleFrom(shape: shape);
return Align(
alignment: const Alignment(0.0, -0.2),
......@@ -260,9 +260,9 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
}
// https://en.wikipedia.org/wiki/Free_Four
String dropdown1Value = 'Free';
String dropdown2Value;
String dropdown3Value = 'Four';
String? dropdown1Value = 'Free';
String? dropdown2Value;
String? dropdown3Value = 'Four';
Widget buildDropdownButton() {
return Padding(
......@@ -274,7 +274,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
title: const Text('Simple dropdown:'),
trailing: DropdownButton<String>(
value: dropdown1Value,
onChanged: (String newValue) {
onChanged: (String? newValue) {
setState(() {
dropdown1Value = newValue;
});
......@@ -295,7 +295,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
trailing: DropdownButton<String>(
value: dropdown2Value,
hint: const Text('Choose'),
onChanged: (String newValue) {
onChanged: (String? newValue) {
setState(() {
dropdown2Value = newValue;
});
......@@ -315,7 +315,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
title: const Text('Scrollable dropdown:'),
trailing: DropdownButton<String>(
value: dropdown3Value,
onChanged: (String newValue) {
onChanged: (String? newValue) {
setState(() {
dropdown3Value = newValue;
});
......
......@@ -17,19 +17,14 @@ enum CardDemoType {
class TravelDestination {
const TravelDestination({
@required this.assetName,
@required this.assetPackage,
@required this.title,
@required this.description,
@required this.city,
@required this.location,
required this.assetName,
required this.assetPackage,
required this.title,
required this.description,
required this.city,
required this.location,
this.type = CardDemoType.standard,
}) : assert(assetName != null),
assert(assetPackage != null),
assert(title != null),
assert(description != null),
assert(city != null),
assert(location != null);
});
final String assetName;
final String assetPackage;
......@@ -70,14 +65,13 @@ const List<TravelDestination> destinations = <TravelDestination>[
];
class TravelDestinationItem extends StatelessWidget {
const TravelDestinationItem({ Key key, @required this.destination, this.shape })
: assert(destination != null),
super(key: key);
const TravelDestinationItem({ Key? key, required this.destination, this.shape })
: super(key: key);
// This height will allow for all the Card's content to fit comfortably within the card.
static const double height = 338.0;
final TravelDestination destination;
final ShapeBorder shape;
final ShapeBorder? shape;
@override
Widget build(BuildContext context) {
......@@ -106,14 +100,13 @@ class TravelDestinationItem extends StatelessWidget {
}
class TappableTravelDestinationItem extends StatelessWidget {
const TappableTravelDestinationItem({ Key key, @required this.destination, this.shape })
: assert(destination != null),
super(key: key);
const TappableTravelDestinationItem({ Key? key, required this.destination, this.shape })
: super(key: key);
// This height will allow for all the Card's content to fit comfortably within the card.
static const double height = 298.0;
final TravelDestination destination;
final ShapeBorder shape;
final ShapeBorder? shape;
@override
Widget build(BuildContext context) {
......@@ -151,12 +144,11 @@ class TappableTravelDestinationItem extends StatelessWidget {
}
class SelectableTravelDestinationItem extends StatefulWidget {
const SelectableTravelDestinationItem({ Key key, @required this.destination, this.shape })
: assert(destination != null),
super(key: key);
const SelectableTravelDestinationItem({ Key? key, required this.destination, this.shape })
: super(key: key);
final TravelDestination destination;
final ShapeBorder shape;
final ShapeBorder? shape;
@override
_SelectableTravelDestinationItemState createState() => _SelectableTravelDestinationItemState();
......@@ -231,11 +223,11 @@ class _SelectableTravelDestinationItemState extends State<SelectableTravelDestin
class SectionTitle extends StatelessWidget {
const SectionTitle({
Key key,
Key? key,
this.title,
}) : super(key: key);
final String title;
final String? title;
@override
Widget build(BuildContext context) {
......@@ -243,24 +235,23 @@ class SectionTitle extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(4.0, 4.0, 4.0, 12.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(title, style: Theme.of(context).textTheme.subtitle1),
child: Text(title!, style: Theme.of(context).textTheme.subtitle1),
),
);
}
}
class TravelDestinationContent extends StatelessWidget {
const TravelDestinationContent({ Key key, @required this.destination })
: assert(destination != null),
super(key: key);
const TravelDestinationContent({ Key? key, required this.destination })
: super(key: key);
final TravelDestination destination;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final TextStyle titleStyle = theme.textTheme.headline5.copyWith(color: Colors.white);
final TextStyle descriptionStyle = theme.textTheme.subtitle1;
final TextStyle titleStyle = theme.textTheme.headline5!.copyWith(color: Colors.white);
final TextStyle descriptionStyle = theme.textTheme.subtitle1!;
final ButtonStyle textButtonStyle = TextButton.styleFrom(primary: Colors.amber.shade500);
return Column(
......@@ -352,7 +343,7 @@ class CardsDemo extends StatefulWidget {
}
class _CardsDemoState extends State<CardsDemo> {
ShapeBorder _shape;
ShapeBorder? _shape;
@override
Widget build(BuildContext context) {
......@@ -385,7 +376,7 @@ class _CardsDemoState extends State<CardsDemo> {
child: ListView(
padding: const EdgeInsets.only(top: 8.0, left: 8.0, right: 8.0),
children: destinations.map<Widget>((TravelDestination destination) {
Widget child;
Widget? child;
switch (destination.type) {
case CardDemoType.standard:
child = TravelDestinationItem(destination: destination, shape: _shape);
......
......@@ -88,13 +88,13 @@ const Map<String, Set<String>> _materialActions = <String, Set<String>>{
class _ChipsTile extends StatelessWidget {
const _ChipsTile({
Key key,
Key? key,
this.label,
this.children,
}) : super(key: key);
final String label;
final List<Widget> children;
final String? label;
final List<Widget>? children;
// Wraps a list of chips into a ListTile for display as a section in the demo.
@override
......@@ -107,11 +107,11 @@ class _ChipsTile extends StatelessWidget {
Container(
padding: const EdgeInsets.only(top: 16.0, bottom: 4.0),
alignment: Alignment.center,
child: Text(label, textAlign: TextAlign.start),
child: Text(label!, textAlign: TextAlign.start),
),
if (children.isNotEmpty)
if (children!.isNotEmpty)
Wrap(
children: children.map<Widget>((Widget chip) {
children: children!.map<Widget>((Widget chip) {
return Padding(
padding: const EdgeInsets.all(2.0),
child: chip,
......@@ -125,7 +125,7 @@ class _ChipsTile extends StatelessWidget {
alignment: Alignment.center,
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
padding: const EdgeInsets.all(8.0),
child: Text('None', style: Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic)),
child: Text('None', style: Theme.of(context).textTheme.caption!.copyWith(fontStyle: FontStyle.italic)),
),
),
],
......@@ -188,7 +188,7 @@ class _ChipDemoState extends State<ChipDemo> {
}
String _capitalize(String name) {
assert(name != null && name.isNotEmpty);
assert(name.isNotEmpty);
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
......@@ -209,7 +209,7 @@ class _ChipDemoState extends State<ChipDemo> {
AssetImage _nameToAvatar(String name) {
assert(_avatars.containsKey(name));
return AssetImage(
_avatars[name],
_avatars[name]!,
package: 'flutter_gallery_assets',
);
}
......@@ -218,7 +218,7 @@ class _ChipDemoState extends State<ChipDemo> {
if (_selectedAction.isEmpty) {
return '';
}
return _capitalize(_results[_selectedAction]) + '!';
return _capitalize(_results[_selectedAction]!) + '!';
}
@override
......@@ -285,11 +285,11 @@ class _ChipDemoState extends State<ChipDemo> {
}).toList();
Set<String> allowedActions = <String>{};
if (_selectedMaterial != null && _selectedMaterial.isNotEmpty) {
if (_selectedMaterial.isNotEmpty) {
for (final String tool in _selectedTools) {
allowedActions.addAll(_toolActions[tool]);
allowedActions.addAll(_toolActions[tool]!);
}
allowedActions = allowedActions.intersection(_materialActions[_selectedMaterial]);
allowedActions = allowedActions.intersection(_materialActions[_selectedMaterial]!);
}
final List<Widget> actionChips = allowedActions.map<Widget>((String name) {
......
......@@ -18,7 +18,7 @@ class Dessert {
final int calcium;
final int iron;
bool selected = false;
bool? selected = false;
}
class DessertDataSource extends DataTableSource {
......@@ -96,17 +96,17 @@ class DessertDataSource extends DataTableSource {
int _selectedCount = 0;
@override
DataRow getRow(int index) {
DataRow? getRow(int index) {
assert(index >= 0);
if (index >= _desserts.length)
return null;
final Dessert dessert = _desserts[index];
return DataRow.byIndex(
index: index,
selected: dessert.selected,
onSelectChanged: (bool value) {
selected: dessert.selected!,
onSelectChanged: (bool? value) {
if (dessert.selected != value) {
_selectedCount += value ? 1 : -1;
_selectedCount += value! ? 1 : -1;
assert(_selectedCount >= 0);
dessert.selected = value;
notifyListeners();
......@@ -134,10 +134,10 @@ class DessertDataSource extends DataTableSource {
@override
int get selectedRowCount => _selectedCount;
void _selectAll(bool checked) {
void _selectAll(bool? checked) {
for (final Dessert dessert in _desserts)
dessert.selected = checked;
_selectedCount = checked ? _desserts.length : 0;
_selectedCount = checked! ? _desserts.length : 0;
notifyListeners();
}
}
......@@ -150,8 +150,8 @@ class DataTableDemo extends StatefulWidget {
}
class _DataTableDemoState extends State<DataTableDemo> {
int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
int _sortColumnIndex;
int? _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
int? _sortColumnIndex;
bool _sortAscending = true;
final DessertDataSource _dessertsDataSource = DessertDataSource();
......@@ -178,8 +178,8 @@ class _DataTableDemoState extends State<DataTableDemo> {
children: <Widget>[
PaginatedDataTable(
header: const Text('Nutrition'),
rowsPerPage: _rowsPerPage,
onRowsPerPageChanged: (int value) { setState(() { _rowsPerPage = value; }); },
rowsPerPage: _rowsPerPage!,
onRowsPerPageChanged: (int? value) { setState(() { _rowsPerPage = value; }); },
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
onSelectAll: _dessertsDataSource._selectAll,
......
......@@ -9,7 +9,7 @@ import '../../gallery/demo.dart';
class _InputDropdown extends StatelessWidget {
const _InputDropdown({
Key key,
Key? key,
this.child,
this.labelText,
this.valueText,
......@@ -17,11 +17,11 @@ class _InputDropdown extends StatelessWidget {
this.onPressed,
}) : super(key: key);
final String labelText;
final String valueText;
final TextStyle valueStyle;
final VoidCallback onPressed;
final Widget child;
final String? labelText;
final String? valueText;
final TextStyle? valueStyle;
final VoidCallback? onPressed;
final Widget? child;
@override
Widget build(BuildContext context) {
......@@ -36,7 +36,7 @@ class _InputDropdown extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(valueText, style: valueStyle),
Text(valueText!, style: valueStyle),
Icon(Icons.arrow_drop_down,
color: Theme.of(context).brightness == Brightness.light ? Colors.grey.shade700 : Colors.white70,
),
......@@ -49,7 +49,7 @@ class _InputDropdown extends StatelessWidget {
class _DateTimePicker extends StatelessWidget {
const _DateTimePicker({
Key key,
Key? key,
this.labelText,
this.selectedDate,
this.selectedTime,
......@@ -57,35 +57,35 @@ class _DateTimePicker extends StatelessWidget {
this.selectTime,
}) : super(key: key);
final String labelText;
final DateTime selectedDate;
final TimeOfDay selectedTime;
final ValueChanged<DateTime> selectDate;
final ValueChanged<TimeOfDay> selectTime;
final String? labelText;
final DateTime? selectedDate;
final TimeOfDay? selectedTime;
final ValueChanged<DateTime>? selectDate;
final ValueChanged<TimeOfDay>? selectTime;
Future<void> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectedDate,
initialDate: selectedDate!,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101),
);
if (picked != null && picked != selectedDate)
selectDate(picked);
selectDate!(picked);
}
Future<void> _selectTime(BuildContext context) async {
final TimeOfDay picked = await showTimePicker(
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: selectedTime,
initialTime: selectedTime!,
);
if (picked != null && picked != selectedTime)
selectTime(picked);
selectTime!(picked);
}
@override
Widget build(BuildContext context) {
final TextStyle valueStyle = Theme.of(context).textTheme.headline6;
final TextStyle? valueStyle = Theme.of(context).textTheme.headline6;
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
......@@ -93,7 +93,7 @@ class _DateTimePicker extends StatelessWidget {
flex: 4,
child: _InputDropdown(
labelText: labelText,
valueText: DateFormat.yMMMd().format(selectedDate),
valueText: DateFormat.yMMMd().format(selectedDate!),
valueStyle: valueStyle,
onPressed: () { _selectDate(context); },
),
......@@ -102,7 +102,7 @@ class _DateTimePicker extends StatelessWidget {
Expanded(
flex: 3,
child: _InputDropdown(
valueText: selectedTime.format(context),
valueText: selectedTime!.format(context),
valueStyle: valueStyle,
onPressed: () { _selectTime(context); },
),
......@@ -125,7 +125,7 @@ class _DateAndTimePickerDemoState extends State<DateAndTimePickerDemo> {
DateTime _toDate = DateTime.now();
TimeOfDay _toTime = const TimeOfDay(hour: 8, minute: 28);
final List<String> _allActivities = <String>['hiking', 'swimming', 'boating', 'fishing'];
String _activity = 'fishing';
String? _activity = 'fishing';
@override
Widget build(BuildContext context) {
......@@ -153,7 +153,7 @@ class _DateAndTimePickerDemoState extends State<DateAndTimePickerDemo> {
decoration: const InputDecoration(
labelText: 'Location',
),
style: Theme.of(context).textTheme.headline4.copyWith(fontSize: 20.0),
style: Theme.of(context).textTheme.headline4!.copyWith(fontSize: 20.0),
),
_DateTimePicker(
labelText: 'From',
......@@ -195,7 +195,7 @@ class _DateAndTimePickerDemoState extends State<DateAndTimePickerDemo> {
isEmpty: _activity == null,
child: DropdownButton<String>(
value: _activity,
onChanged: (String newValue) {
onChanged: (String? newValue) {
setState(() {
_activity = newValue;
});
......
......@@ -21,12 +21,12 @@ const String _alertWithTitleText =
'data to Google, even when no apps are running.';
class DialogDemoItem extends StatelessWidget {
const DialogDemoItem({ Key key, this.icon, this.color, this.text, this.onPressed }) : super(key: key);
const DialogDemoItem({ Key? key, this.icon, this.color, this.text, this.onPressed }) : super(key: key);
final IconData icon;
final Color color;
final String text;
final VoidCallback onPressed;
final IconData? icon;
final Color? color;
final String? text;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
......@@ -39,7 +39,7 @@ class DialogDemoItem extends StatelessWidget {
Icon(icon, size: 36.0, color: color),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Text(text),
child: Text(text!),
),
],
),
......@@ -56,7 +56,7 @@ class DialogDemo extends StatefulWidget {
class DialogDemoState extends State<DialogDemo> {
TimeOfDay _selectedTime;
TimeOfDay? _selectedTime;
@override
void initState() {
......@@ -65,12 +65,12 @@ class DialogDemoState extends State<DialogDemo> {
_selectedTime = TimeOfDay(hour: now.hour, minute: now.minute);
}
void showDemoDialog<T>({ BuildContext context, Widget child }) {
void showDemoDialog<T>({ required BuildContext context, Widget? child }) {
showDialog<T>(
context: context,
builder: (BuildContext context) => child,
builder: (BuildContext context) => child!,
)
.then<void>((T value) { // The value passed to Navigator.pop() or null.
.then((T? value) { // The value passed to Navigator.pop() or null.
if (value != null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('You selected: $value'),
......@@ -82,7 +82,7 @@ class DialogDemoState extends State<DialogDemo> {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = theme.textTheme.subtitle1.copyWith(color: theme.textTheme.caption.color);
final TextStyle dialogTextStyle = theme.textTheme.subtitle1!.copyWith(color: theme.textTheme.caption!.color);
return Scaffold(
appBar: AppBar(
......@@ -176,9 +176,9 @@ class DialogDemoState extends State<DialogDemo> {
onPressed: () {
showTimePicker(
context: context,
initialTime: _selectedTime,
initialTime: _selectedTime!,
)
.then<void>((TimeOfDay value) {
.then((TimeOfDay? value) {
if (value != null && value != _selectedTime) {
_selectedTime = value;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
......
......@@ -33,9 +33,9 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
curve: Curves.fastOutSlowIn,
));
AnimationController _controller;
Animation<double> _drawerContentsOpacity;
Animation<Offset> _drawerDetailsPosition;
late AnimationController _controller;
late Animation<double> _drawerContentsOpacity;
late Animation<Offset> _drawerDetailsPosition;
bool _showDrawerContents = true;
@override
......@@ -58,7 +58,7 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
super.dispose();
}
IconData _backIcon() {
IconData? _backIcon() {
switch (Theme.of(context).platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
......@@ -69,8 +69,6 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
case TargetPlatform.macOS:
return Icons.arrow_back_ios;
}
assert(false);
return null;
}
void _showNotImplementedMessage() {
......@@ -211,7 +209,7 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
body: Center(
child: InkWell(
onTap: () {
_scaffoldKey.currentState.openDrawer();
_scaffoldKey.currentState!.openDrawer();
},
child: Semantics(
button: true,
......
......@@ -14,7 +14,7 @@ enum Location {
}
typedef DemoItemBodyBuilder<T> = Widget Function(DemoItem<T> item);
typedef ValueToString<T> = String Function(T value);
typedef ValueToString<T> = String? Function(T value);
class DualHeaderWithHint extends StatelessWidget {
const DualHeaderWithHint({
......@@ -24,10 +24,10 @@ class DualHeaderWithHint extends StatelessWidget {
this.showHint,
});
final String name;
final String value;
final String hint;
final bool showHint;
final String? name;
final String? value;
final String? hint;
final bool? showHint;
Widget _crossFade(Widget first, Widget second, bool isExpanded) {
return AnimatedCrossFade(
......@@ -56,8 +56,8 @@ class DualHeaderWithHint extends StatelessWidget {
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
name,
style: textTheme.bodyText2.copyWith(fontSize: 15.0),
name!,
style: textTheme.bodyText2!.copyWith(fontSize: 15.0),
),
),
),
......@@ -67,9 +67,9 @@ class DualHeaderWithHint extends StatelessWidget {
child: Container(
margin: const EdgeInsets.only(left: 24.0),
child: _crossFade(
Text(value, style: textTheme.caption.copyWith(fontSize: 15.0)),
Text(hint, style: textTheme.caption.copyWith(fontSize: 15.0)),
showHint,
Text(value!, style: textTheme.caption!.copyWith(fontSize: 15.0)),
Text(hint!, style: textTheme.caption!.copyWith(fontSize: 15.0)),
showHint!,
),
),
),
......@@ -87,9 +87,9 @@ class CollapsibleBody extends StatelessWidget {
});
final EdgeInsets margin;
final Widget child;
final VoidCallback onSave;
final VoidCallback onCancel;
final Widget? child;
final VoidCallback? onSave;
final VoidCallback? onCancel;
@override
Widget build(BuildContext context) {
......@@ -106,8 +106,8 @@ class CollapsibleBody extends StatelessWidget {
) - margin,
child: Center(
child: DefaultTextStyle(
style: textTheme.caption.copyWith(fontSize: 15.0),
child: child,
style: textTheme.caption!.copyWith(fontSize: 15.0),
child: child!,
),
),
),
......@@ -149,15 +149,15 @@ class DemoItem<T> {
this.value,
this.hint,
this.builder,
this.valueToString,
required this.valueToString,
}) : textController = TextEditingController(text: valueToString(value));
final String name;
final String hint;
final String? name;
final String? hint;
final TextEditingController textController;
final DemoItemBodyBuilder<T> builder;
final ValueToString<T> valueToString;
T value;
final DemoItemBodyBuilder<T>? builder;
final ValueToString<T?> valueToString;
T? value;
bool isExpanded = false;
ExpansionPanelHeaderBuilder get headerBuilder {
......@@ -171,7 +171,7 @@ class DemoItem<T> {
};
}
Widget build() => builder(this);
Widget build() => builder!(this);
}
class ExpansionPanelsDemo extends StatefulWidget {
......@@ -182,7 +182,7 @@ class ExpansionPanelsDemo extends StatefulWidget {
}
class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
List<DemoItem<dynamic>> _demoItems;
late List<DemoItem<dynamic>> _demoItems;
@override
void initState() {
......@@ -193,7 +193,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
name: 'Trip',
value: 'Caribbean cruise',
hint: 'Change trip name',
valueToString: (String value) => value,
valueToString: (String? value) => value,
builder: (DemoItem<String> item) {
void close() {
setState(() {
......@@ -206,8 +206,8 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
builder: (BuildContext context) {
return CollapsibleBody(
margin: const EdgeInsets.symmetric(horizontal: 16.0),
onSave: () { Form.of(context).save(); close(); },
onCancel: () { Form.of(context).reset(); close(); },
onSave: () { Form.of(context)!.save(); close(); },
onCancel: () { Form.of(context)!.reset(); close(); },
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: TextFormField(
......@@ -216,7 +216,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
hintText: item.hint,
labelText: item.name,
),
onSaved: (String value) { item.value = value; },
onSaved: (String? value) { item.value = value; },
),
),
);
......@@ -229,7 +229,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
name: 'Location',
value: Location.Bahamas,
hint: 'Select location',
valueToString: (Location location) => location.toString().split('.')[1],
valueToString: (Location? location) => location.toString().split('.')[1],
builder: (DemoItem<Location> item) {
void close() {
setState(() {
......@@ -240,11 +240,11 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
child: Builder(
builder: (BuildContext context) {
return CollapsibleBody(
onSave: () { Form.of(context).save(); close(); },
onCancel: () { Form.of(context).reset(); close(); },
onSave: () { Form.of(context)!.save(); close(); },
onCancel: () { Form.of(context)!.reset(); close(); },
child: FormField<Location>(
initialValue: item.value,
onSaved: (Location result) { item.value = result; },
onSaved: (Location? result) { item.value = result; },
builder: (FormFieldState<Location> field) {
return Column(
mainAxisSize: MainAxisSize.min,
......@@ -282,7 +282,7 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
name: 'Sun',
value: 80.0,
hint: 'Select sun level',
valueToString: (double amount) => '${amount.round()}',
valueToString: (double? amount) => '${amount!.round()}',
builder: (DemoItem<double> item) {
void close() {
setState(() {
......@@ -294,11 +294,11 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
child: Builder(
builder: (BuildContext context) {
return CollapsibleBody(
onSave: () { Form.of(context).save(); close(); },
onCancel: () { Form.of(context).reset(); close(); },
onSave: () { Form.of(context)!.save(); close(); },
onCancel: () { Form.of(context)!.reset(); close(); },
child: FormField<double>(
initialValue: item.value,
onSaved: (double value) { item.value = value; },
onSaved: (double? value) { item.value = value; },
builder: (FormFieldState<double> field) {
return Container(
// Allow room for the value indicator.
......@@ -307,9 +307,9 @@ class _ExpansionPanelsDemoState extends State<ExpansionPanelsDemo> {
min: 0.0,
max: 100.0,
divisions: 5,
activeColor: Colors.orange[100 + (field.value * 5.0).round()],
label: '${field.value.round()}',
value: field.value,
activeColor: Colors.orange[100 + (field.value! * 5.0).round()],
label: '${field.value!.round()}',
value: field.value!,
onChanged: field.didChange,
),
);
......
......@@ -15,9 +15,8 @@ enum DismissDialogAction {
}
class DateTimeItem extends StatelessWidget {
DateTimeItem({ Key key, DateTime dateTime, @required this.onChanged })
: assert(onChanged != null),
date = DateTime(dateTime.year, dateTime.month, dateTime.day),
DateTimeItem({ Key? key, required DateTime dateTime, required this.onChanged })
: date = DateTime(dateTime.year, dateTime.month, dateTime.day),
time = TimeOfDay(hour: dateTime.hour, minute: dateTime.minute),
super(key: key);
......@@ -30,7 +29,7 @@ class DateTimeItem extends StatelessWidget {
final ThemeData theme = Theme.of(context);
return DefaultTextStyle(
style: theme.textTheme.subtitle1,
style: theme.textTheme.subtitle1!,
child: Row(
children: <Widget>[
Expanded(
......@@ -47,7 +46,7 @@ class DateTimeItem extends StatelessWidget {
firstDate: date.subtract(const Duration(days: 30)),
lastDate: date.add(const Duration(days: 30)),
)
.then<void>((DateTime value) {
.then((DateTime? value) {
if (value != null)
onChanged(DateTime(value.year, value.month, value.day, time.hour, time.minute));
});
......@@ -74,7 +73,7 @@ class DateTimeItem extends StatelessWidget {
context: context,
initialTime: time,
)
.then<void>((TimeOfDay value) {
.then((TimeOfDay? value) {
if (value != null)
onChanged(DateTime(date.year, date.month, date.day, value.hour, value.minute));
});
......@@ -101,11 +100,11 @@ class FullScreenDialogDemo extends StatefulWidget {
class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
DateTime _fromDateTime = DateTime.now();
DateTime _toDateTime = DateTime.now();
bool _allDayValue = false;
bool? _allDayValue = false;
bool _saveNeeded = false;
bool _hasLocation = false;
bool _hasName = false;
String _eventName;
late String _eventName;
Future<bool> _onWillPop() async {
_saveNeeded = _hasLocation || _hasName || _saveNeeded;
......@@ -113,9 +112,9 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
return true;
final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = theme.textTheme.subtitle1.copyWith(color: theme.textTheme.caption.color);
final TextStyle dialogTextStyle = theme.textTheme.subtitle1!.copyWith(color: theme.textTheme.caption!.color);
return await showDialog<bool>(
return await (showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
......@@ -127,19 +126,19 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
TextButton(
child: const Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop(false); // Pops the confirmation dialog but not the page.
Navigator.of(context)!.pop(false); // Pops the confirmation dialog but not the page.
},
),
TextButton(
child: const Text('DISCARD'),
onPressed: () {
Navigator.of(context).pop(true); // Returning true to _onWillPop will pop again.
Navigator.of(context)!.pop(true); // Returning true to _onWillPop will pop again.
},
),
],
);
},
) ?? false;
) as Future<bool>);
}
@override
......@@ -151,7 +150,7 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
title: Text(_hasName ? _eventName : 'Event Name TBD'),
actions: <Widget> [
TextButton(
child: Text('SAVE', style: theme.textTheme.bodyText2.copyWith(color: Colors.white)),
child: Text('SAVE', style: theme.textTheme.bodyText2!.copyWith(color: Colors.white)),
onPressed: () {
Navigator.pop(context, DismissDialogAction.save);
},
......@@ -238,7 +237,7 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
children: <Widget> [
Checkbox(
value: _allDayValue,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
_allDayValue = value;
_saveNeeded = true;
......
......@@ -26,21 +26,21 @@ class Photo {
this.isFavorite = false,
});
final String assetName;
final String assetPackage;
final String title;
final String caption;
final String? assetName;
final String? assetPackage;
final String? title;
final String? caption;
bool isFavorite;
String get tag => assetName; // Assuming that all asset names are unique.
String? get tag => assetName; // Assuming that all asset names are unique.
bool get isValid => assetName != null && title != null && caption != null && isFavorite != null;
bool get isValid => assetName != null && title != null && caption != null;
}
class GridPhotoViewer extends StatefulWidget {
const GridPhotoViewer({ Key key, this.photo }) : super(key: key);
const GridPhotoViewer({ Key? key, this.photo }) : super(key: key);
final Photo photo;
final Photo? photo;
@override
_GridPhotoViewerState createState() => _GridPhotoViewerState();
......@@ -49,25 +49,25 @@ class GridPhotoViewer extends StatefulWidget {
class _GridTitleText extends StatelessWidget {
const _GridTitleText(this.text);
final String text;
final String? text;
@override
Widget build(BuildContext context) {
return FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(text),
child: Text(text!),
);
}
}
class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<Offset> _flingAnimation;
late AnimationController _controller;
late Animation<Offset> _flingAnimation;
Offset _offset = Offset.zero;
double _scale = 1.0;
Offset _normalizedOffset;
double _previousScale;
late Offset _normalizedOffset;
late double _previousScale;
@override
void initState() {
......@@ -85,11 +85,11 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
// The maximum offset value is 0,0. If the size of this renderer's box is w,h
// then the minimum offset value is w - _scale * w, h - _scale * h.
Offset _clampOffset(Offset offset) {
final Size size = context.size;
final Size size = context.size!;
final Offset minOffset = Offset(size.width, size.height) * (1.0 - _scale);
return Offset(
offset.dx.clamp(minOffset.dx, 0.0) as double,
offset.dy.clamp(minOffset.dy, 0.0) as double,
offset.dx.clamp(minOffset.dx, 0.0),
offset.dy.clamp(minOffset.dy, 0.0),
);
}
......@@ -110,7 +110,7 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
void _handleOnScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_scale = (_previousScale * details.scale).clamp(1.0, 4.0) as double;
_scale = (_previousScale * details.scale).clamp(1.0, 4.0);
// Ensure that image location under the focal point stays in the same place despite scaling.
_offset = _clampOffset(details.focalPoint - _normalizedOffset * _scale);
});
......@@ -121,7 +121,7 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
if (magnitude < _kMinFlingVelocity)
return;
final Offset direction = details.velocity.pixelsPerSecond / magnitude;
final double distance = (Offset.zero & context.size).shortestSide;
final double distance = (Offset.zero & context.size!).shortestSide;
_flingAnimation = _controller.drive(Tween<Offset>(
begin: _offset,
end: _clampOffset(_offset + direction * distance),
......@@ -143,8 +143,8 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
..translate(_offset.dx, _offset.dy)
..scale(_scale),
child: Image.asset(
widget.photo.assetName,
package: widget.photo.assetPackage,
widget.photo!.assetName!,
package: widget.photo!.assetPackage,
fit: BoxFit.cover,
),
),
......@@ -155,13 +155,11 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
class GridDemoPhotoItem extends StatelessWidget {
GridDemoPhotoItem({
Key key,
@required this.photo,
@required this.tileStyle,
@required this.onBannerTap,
}) : assert(photo != null && photo.isValid),
assert(tileStyle != null),
assert(onBannerTap != null),
Key? key,
required this.photo,
required this.tileStyle,
required this.onBannerTap,
}) : assert(photo.isValid),
super(key: key);
final Photo photo;
......@@ -173,11 +171,11 @@ class GridDemoPhotoItem extends StatelessWidget {
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(photo.title),
title: Text(photo.title!),
),
body: SizedBox.expand(
child: Hero(
tag: photo.tag,
tag: photo.tag!,
child: GridPhotoViewer(photo: photo),
),
),
......@@ -193,10 +191,10 @@ class GridDemoPhotoItem extends StatelessWidget {
child: GestureDetector(
onTap: () { showPhoto(context); },
child: Hero(
key: Key(photo.assetName),
tag: photo.tag,
key: Key(photo.assetName!),
tag: photo.tag!,
child: Image.asset(
photo.assetName,
photo.assetName!,
package: photo.assetPackage,
fit: BoxFit.cover,
),
......@@ -243,13 +241,11 @@ class GridDemoPhotoItem extends StatelessWidget {
child: image,
);
}
assert(tileStyle != null);
return null;
}
}
class GridListDemo extends StatefulWidget {
const GridListDemo({ Key key }) : super(key: key);
const GridListDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/grid-list';
......
......@@ -109,7 +109,7 @@ class _IconsDemoCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final TextStyle textStyle = theme.textTheme.subtitle1.copyWith(color: theme.textTheme.caption.color);
final TextStyle textStyle = theme.textTheme.subtitle1!.copyWith(color: theme.textTheme.caption!.color);
return Card(
child: DefaultTextStyle(
style: textStyle,
......
......@@ -23,17 +23,17 @@ class LeaveBehindItem implements Comparable<LeaveBehindItem> {
LeaveBehindItem.from(LeaveBehindItem item)
: index = item.index, name = item.name, subject = item.subject, body = item.body;
final int index;
final String name;
final String subject;
final String body;
final int? index;
final String? name;
final String? subject;
final String? body;
@override
int compareTo(LeaveBehindItem other) => index.compareTo(other.index);
int compareTo(LeaveBehindItem other) => index!.compareTo(other.index!);
}
class LeaveBehindDemo extends StatefulWidget {
const LeaveBehindDemo({ Key key }) : super(key: key);
const LeaveBehindDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/leave-behind';
......@@ -44,7 +44,7 @@ class LeaveBehindDemo extends StatefulWidget {
class LeaveBehindDemoState extends State<LeaveBehindDemo> {
DismissDirection _dismissDirection = DismissDirection.horizontal;
bool _confirmDismiss = true;
List<LeaveBehindItem> leaveBehindItems;
late List<LeaveBehindItem> leaveBehindItems;
void initListItems() {
leaveBehindItems = List<LeaveBehindItem>.generate(16, (int index) {
......@@ -188,12 +188,12 @@ class LeaveBehindDemoState extends State<LeaveBehindDemo> {
class _LeaveBehindListItem extends StatelessWidget {
const _LeaveBehindListItem({
Key key,
@required this.item,
@required this.onArchive,
@required this.onDelete,
@required this.dismissDirection,
@required this.confirmDismiss,
Key? key,
required this.item,
required this.onArchive,
required this.onDelete,
required this.dismissDirection,
required this.confirmDismiss,
}) : super(key: key);
final LeaveBehindItem item;
......@@ -263,7 +263,7 @@ class _LeaveBehindListItem extends StatelessWidget {
border: Border(bottom: BorderSide(color: theme.dividerColor)),
),
child: ListTile(
title: Text(item.name),
title: Text(item.name!),
subtitle: Text('${item.subject}\n${item.body}'),
isThreeLine: true,
),
......@@ -272,7 +272,7 @@ class _LeaveBehindListItem extends StatelessWidget {
);
}
Future<bool> _showConfirmationDialog(BuildContext context, String action) {
Future<bool?> _showConfirmationDialog(BuildContext context, String action) {
return showDialog<bool>(
context: context,
barrierDismissible: true,
......
......@@ -21,7 +21,7 @@ enum _MaterialListType {
}
class ListDemo extends StatefulWidget {
const ListDemo({ Key key }) : super(key: key);
const ListDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/list';
......@@ -32,26 +32,26 @@ class ListDemo extends StatefulWidget {
class _ListDemoState extends State<ListDemo> {
static final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
PersistentBottomSheetController<void> _bottomSheet;
_MaterialListType _itemType = _MaterialListType.threeLine;
bool _dense = false;
bool _showAvatars = true;
bool _showIcons = false;
bool _showDividers = false;
PersistentBottomSheetController<void>? _bottomSheet;
_MaterialListType? _itemType = _MaterialListType.threeLine;
bool? _dense = false;
bool? _showAvatars = true;
bool? _showIcons = false;
bool? _showDividers = false;
bool _reverseSort = false;
List<String> items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
];
void changeItemType(_MaterialListType type) {
void changeItemType(_MaterialListType? type) {
setState(() {
_itemType = type;
});
_bottomSheet?.setState(() { });
_bottomSheet?.setState!(() { });
}
void _showConfigurationSheet() {
final PersistentBottomSheetController<void> bottomSheet = scaffoldKey.currentState.showBottomSheet<void>((BuildContext bottomSheetContext) {
final PersistentBottomSheetController<void> bottomSheet = scaffoldKey.currentState!.showBottomSheet<void>((BuildContext bottomSheetContext) {
return Container(
decoration: const BoxDecoration(
border: Border(top: BorderSide(color: Colors.black26)),
......@@ -65,7 +65,7 @@ class _ListDemoState extends State<ListDemo> {
dense: true,
title: const Text('One-line'),
trailing: Radio<_MaterialListType>(
value: _showAvatars ? _MaterialListType.oneLineWithAvatar : _MaterialListType.oneLine,
value: _showAvatars! ? _MaterialListType.oneLineWithAvatar : _MaterialListType.oneLine,
groupValue: _itemType,
onChanged: changeItemType,
),
......@@ -99,11 +99,14 @@ class _ListDemoState extends State<ListDemo> {
title: const Text('Show avatar'),
trailing: Checkbox(
value: _showAvatars,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
_showAvatars = value;
});
_bottomSheet?.setState(() { });
final StateSetter? bottomSheetSetState = _bottomSheet?.setState;
if (bottomSheetSetState != null) {
bottomSheetSetState(() { });
}
},
),
),
......@@ -114,11 +117,14 @@ class _ListDemoState extends State<ListDemo> {
title: const Text('Show icon'),
trailing: Checkbox(
value: _showIcons,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
_showIcons = value;
});
_bottomSheet?.setState(() { });
final StateSetter? bottomSheetSetState = _bottomSheet?.setState;
if (bottomSheetSetState != null) {
bottomSheetSetState(() { });
}
},
),
),
......@@ -129,11 +135,14 @@ class _ListDemoState extends State<ListDemo> {
title: const Text('Show dividers'),
trailing: Checkbox(
value: _showDividers,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
_showDividers = value;
});
_bottomSheet?.setState(() { });
final StateSetter? bottomSheetSetState = _bottomSheet?.setState;
if (bottomSheetSetState != null) {
bottomSheetSetState(() { });
}
},
),
),
......@@ -144,11 +153,14 @@ class _ListDemoState extends State<ListDemo> {
title: const Text('Dense layout'),
trailing: Checkbox(
value: _dense,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
_dense = value;
});
_bottomSheet?.setState(() { });
final StateSetter? bottomSheetSetState = _bottomSheet?.setState;
if (bottomSheetSetState != null) {
bottomSheetSetState(() { });
}
},
),
),
......@@ -162,7 +174,7 @@ class _ListDemoState extends State<ListDemo> {
_bottomSheet = bottomSheet;
});
_bottomSheet.closed.whenComplete(() {
_bottomSheet?.closed.whenComplete(() {
if (mounted) {
setState(() {
_bottomSheet = null;
......@@ -172,7 +184,7 @@ class _ListDemoState extends State<ListDemo> {
}
Widget buildListTile(BuildContext context, String item) {
Widget secondary;
Widget? secondary;
if (_itemType == _MaterialListType.twoLine) {
secondary = const Text('Additional item information.');
} else if (_itemType == _MaterialListType.threeLine) {
......@@ -184,18 +196,18 @@ class _ListDemoState extends State<ListDemo> {
child: ListTile(
isThreeLine: _itemType == _MaterialListType.threeLine,
dense: _dense,
leading: _showAvatars ? ExcludeSemantics(child: CircleAvatar(child: Text(item))) : null,
leading: _showAvatars != null ? ExcludeSemantics(child: CircleAvatar(child: Text(item))) : null,
title: Text('This item represents $item.'),
subtitle: secondary,
trailing: _showIcons ? Icon(Icons.info, color: Theme.of(context).disabledColor) : null,
trailing: _showIcons != null ? Icon(Icons.info, color: Theme.of(context).disabledColor) : null,
),
);
}
@override
Widget build(BuildContext context) {
final String layoutText = _dense ? ' \u2013 Dense' : '';
String itemTypeText;
final String layoutText = _dense != null ? ' \u2013 Dense' : '';
String? itemTypeText;
switch (_itemType) {
case _MaterialListType.oneLine:
case _MaterialListType.oneLineWithAvatar:
......@@ -207,10 +219,12 @@ class _ListDemoState extends State<ListDemo> {
case _MaterialListType.threeLine:
itemTypeText = 'Three-line';
break;
default:
break;
}
Iterable<Widget> listTiles = items.map<Widget>((String item) => buildListTile(context, item));
if (_showDividers)
if (_showDividers != null)
listTiles = ListTile.divideTiles(context: context, tiles: listTiles);
return Scaffold(
......@@ -242,7 +256,7 @@ class _ListDemoState extends State<ListDemo> {
),
body: Scrollbar(
child: ListView(
padding: EdgeInsets.symmetric(vertical: _dense ? 4.0 : 8.0),
padding: EdgeInsets.symmetric(vertical: _dense != null ? 4.0 : 8.0),
children: listTiles.toList(),
),
),
......
......@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import '../../gallery/demo.dart';
class MenuDemo extends StatefulWidget {
const MenuDemo({ Key key }) : super(key: key);
const MenuDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/menu';
......@@ -20,13 +20,13 @@ class MenuDemoState extends State<MenuDemo> {
final String _simpleValue1 = 'Menu item value one';
final String _simpleValue2 = 'Menu item value two';
final String _simpleValue3 = 'Menu item value three';
String _simpleValue;
String? _simpleValue;
final String _checkedValue1 = 'One';
final String _checkedValue2 = 'Two';
final String _checkedValue3 = 'Free';
final String _checkedValue4 = 'Four';
List<String> _checkedValues;
late List<String> _checkedValues;
@override
void initState() {
......@@ -165,7 +165,7 @@ class MenuDemoState extends State<MenuDemo> {
onSelected: showMenuSelection,
child: ListTile(
title: const Text('An item with a simple menu'),
subtitle: Text(_simpleValue),
subtitle: Text(_simpleValue!),
),
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
PopupMenuItem<String>(
......
......@@ -11,7 +11,7 @@ import '../../gallery/demo.dart';
enum IndicatorType { overscroll, refresh }
class OverscrollDemo extends StatefulWidget {
const OverscrollDemo({ Key key }) : super(key: key);
const OverscrollDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/overscroll';
......@@ -28,13 +28,13 @@ class OverscrollDemoState extends State<OverscrollDemo> {
Future<void> _handleRefresh() {
final Completer<void> completer = Completer<void>();
Timer(const Duration(seconds: 3), () { completer.complete(); });
return completer.future.then<void>((_) {
return completer.future.then((_) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Refresh complete'),
action: SnackBarAction(
label: 'RETRY',
onPressed: () {
_refreshIndicatorKey.currentState.show();
_refreshIndicatorKey.currentState!.show();
},
),
));
......@@ -52,7 +52,7 @@ class OverscrollDemoState extends State<OverscrollDemo> {
icon: const Icon(Icons.refresh),
tooltip: 'Refresh',
onPressed: () {
_refreshIndicatorKey.currentState.show();
_refreshIndicatorKey.currentState!.show();
},
),
],
......
......@@ -9,17 +9,17 @@ import '../../gallery/demo.dart';
class _PageSelector extends StatelessWidget {
const _PageSelector({ this.icons });
final List<Icon> icons;
final List<Icon>? icons;
void _handleArrowButtonPress(BuildContext context, int delta) {
final TabController controller = DefaultTabController.of(context);
final TabController controller = DefaultTabController.of(context)!;
if (!controller.indexIsChanging)
controller.animateTo((controller.index + delta).clamp(0, icons.length - 1) as int);
controller.animateTo((controller.index + delta).clamp(0, icons!.length - 1));
}
@override
Widget build(BuildContext context) {
final TabController controller = DefaultTabController.of(context);
final TabController? controller = DefaultTabController.of(context);
final Color color = Theme.of(context).accentColor;
return SafeArea(
top: false,
......@@ -54,7 +54,7 @@ class _PageSelector extends StatelessWidget {
color: color,
),
child: TabBarView(
children: icons.map<Widget>((Icon icon) {
children: icons!.map<Widget>((Icon icon) {
return Container(
padding: const EdgeInsets.all(12.0),
child: Card(
......
......@@ -16,7 +16,7 @@ class PersistentBottomSheetDemo extends StatefulWidget {
class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
VoidCallback _showBottomSheetCallback;
VoidCallback? _showBottomSheetCallback;
@override
void initState() {
......@@ -28,7 +28,7 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
setState(() { // disable the button
_showBottomSheetCallback = null;
});
_scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) {
_scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) {
final ThemeData themeData = Theme.of(context);
return Container(
decoration: BoxDecoration(
......
......@@ -14,8 +14,8 @@ class ProgressIndicatorDemo extends StatefulWidget {
}
class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
......@@ -64,7 +64,7 @@ class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with Sing
});
}
Widget _buildIndicators(BuildContext context, Widget child) {
Widget _buildIndicators(BuildContext context, Widget? child) {
final List<Widget> indicators = <Widget>[
const SizedBox(
width: 200.0,
......@@ -109,7 +109,7 @@ class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with Sing
body: Center(
child: SingleChildScrollView(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.headline6!,
child: GestureDetector(
onTap: _handleTap,
behavior: HitTestBehavior.opaque,
......
......@@ -20,7 +20,7 @@ enum _ReorderableListType {
}
class ReorderableListDemo extends StatefulWidget {
const ReorderableListDemo({ Key key }) : super(key: key);
const ReorderableListDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/reorderable-list';
......@@ -33,38 +33,38 @@ class _ListItem {
final String value;
bool checkState;
bool? checkState;
}
class _ListDemoState extends State<ReorderableListDemo> {
static final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
PersistentBottomSheetController<void> _bottomSheet;
_ReorderableListType _itemType = _ReorderableListType.threeLine;
bool _reverse = false;
PersistentBottomSheetController<void>? _bottomSheet;
_ReorderableListType? _itemType = _ReorderableListType.threeLine;
bool? _reverse = false;
bool _reverseSort = false;
final List<_ListItem> _items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
].map<_ListItem>((String item) => _ListItem(item, false)).toList();
void changeItemType(_ReorderableListType type) {
void changeItemType(_ReorderableListType? type) {
setState(() {
_itemType = type;
});
// Rebuild the bottom sheet to reflect the selected list view.
_bottomSheet?.setState(() {
_bottomSheet?.setState!(() {
// Trigger a rebuild.
});
// Close the bottom sheet to give the user a clear view of the list.
_bottomSheet?.close();
}
void changeReverse(bool newValue) {
void changeReverse(bool? newValue) {
setState(() {
_reverse = newValue;
});
// Rebuild the bottom sheet to reflect the selected list view.
_bottomSheet?.setState(() {
_bottomSheet?.setState!(() {
// Trigger a rebuild.
});
// Close the bottom sheet to give the user a clear view of the list.
......@@ -73,7 +73,7 @@ class _ListDemoState extends State<ReorderableListDemo> {
void _showConfigurationSheet() {
setState(() {
_bottomSheet = scaffoldKey.currentState.showBottomSheet<void>((BuildContext bottomSheetContext) {
_bottomSheet = scaffoldKey.currentState!.showBottomSheet<void>((BuildContext bottomSheetContext) {
return DecoratedBox(
decoration: const BoxDecoration(
border: Border(top: BorderSide(color: Colors.black26)),
......@@ -115,7 +115,7 @@ class _ListDemoState extends State<ReorderableListDemo> {
});
// Garbage collect the bottom sheet when it closes.
_bottomSheet.closed.whenComplete(() {
_bottomSheet?.closed.whenComplete(() {
if (mounted) {
setState(() {
_bottomSheet = null;
......@@ -129,14 +129,14 @@ class _ListDemoState extends State<ReorderableListDemo> {
const Widget secondary = Text(
'Even more additional list item information appears on line three.',
);
Widget listTile;
late Widget listTile;
switch (_itemType) {
case _ReorderableListType.threeLine:
listTile = CheckboxListTile(
key: Key(item.value),
isThreeLine: true,
value: item.checkState ?? false,
onChanged: (bool newValue) {
onChanged: (bool? newValue) {
setState(() {
item.checkState = newValue;
});
......@@ -157,6 +157,11 @@ class _ListDemoState extends State<ReorderableListDemo> {
),
);
break;
default:
listTile = Container(
key: Key(item.value),
);
break;
}
return listTile;
......@@ -210,7 +215,7 @@ class _ListDemoState extends State<ReorderableListDemo> {
child: Text('Header of the list', style: Theme.of(context).textTheme.headline5))
: null,
onReorder: _onReorder,
reverse: _reverse,
reverse: _reverse!,
scrollDirection: _itemType == _ReorderableListType.horizontalAvatar ? Axis.horizontal : Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: _items.map<Widget>(buildListTile).toList(),
......
......@@ -14,8 +14,8 @@ enum TabsDemoStyle {
class _Page {
const _Page({ this.icon, this.text });
final IconData icon;
final String text;
final IconData? icon;
final String? text;
}
const List<_Page> _allPages = <_Page>[
......@@ -43,7 +43,7 @@ class ScrollableTabsDemo extends StatefulWidget {
}
class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTickerProviderStateMixin {
TabController _controller;
TabController? _controller;
TabsDemoStyle _demoStyle = TabsDemoStyle.iconsAndText;
bool _customIndicator = false;
......@@ -55,7 +55,7 @@ class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTicke
@override
void dispose() {
_controller.dispose();
_controller!.dispose();
super.dispose();
}
......@@ -65,7 +65,7 @@ class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTicke
});
}
Decoration getIndicator() {
Decoration? getIndicator() {
if (!_customIndicator)
return const UnderlineTabIndicator();
......@@ -117,7 +117,6 @@ class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTicke
),
);
}
return null;
}
@override
......@@ -161,7 +160,6 @@ class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTicke
isScrollable: true,
indicator: getIndicator(),
tabs: _allPages.map<Tab>((_Page page) {
assert(_demoStyle != null);
switch (_demoStyle) {
case TabsDemoStyle.iconsAndText:
return Tab(text: page.text, icon: Icon(page.icon));
......@@ -169,9 +167,10 @@ class ScrollableTabsDemoState extends State<ScrollableTabsDemo> with SingleTicke
return Tab(icon: Icon(page.icon));
case TabsDemoStyle.textOnly:
return Tab(text: page.text);
default:
return Tab();
}
return null;
}).toList(),
}).toList()
),
),
body: TabBarView(
......
......@@ -17,7 +17,7 @@ class _SearchDemoState extends State<SearchDemo> {
final _SearchDemoSearchDelegate _delegate = _SearchDemoSearchDelegate();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
int _lastIntegerSelected;
int? _lastIntegerSelected;
@override
Widget build(BuildContext context) {
......@@ -32,7 +32,7 @@ class _SearchDemoState extends State<SearchDemo> {
progress: _delegate.transitionAnimation,
),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
_scaffoldKey.currentState!.openDrawer();
},
),
title: const Text('Numbers'),
......@@ -41,7 +41,7 @@ class _SearchDemoState extends State<SearchDemo> {
tooltip: 'Search',
icon: const Icon(Icons.search),
onPressed: () async {
final int selected = await showSearch<int>(
final int? selected = await showSearch<int?>(
context: context,
delegate: _delegate,
);
......@@ -98,7 +98,7 @@ class _SearchDemoState extends State<SearchDemo> {
floatingActionButton: FloatingActionButton.extended(
tooltip: 'Back', // Tests depend on this label to exit the demo.
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context)!.pop();
},
label: const Text('Close demo'),
icon: const Icon(Icons.close),
......@@ -133,7 +133,7 @@ class _SearchDemoState extends State<SearchDemo> {
}
}
class _SearchDemoSearchDelegate extends SearchDelegate<int> {
class _SearchDemoSearchDelegate extends SearchDelegate<int?> {
final List<int> _data = List<int>.generate(100001, (int i) => i).reversed.toList();
final List<int> _history = <int>[42607, 85604, 66374, 44, 174];
......@@ -170,7 +170,7 @@ class _SearchDemoSearchDelegate extends SearchDelegate<int> {
@override
Widget buildResults(BuildContext context) {
final int searched = int.tryParse(query);
final int? searched = int.tryParse(query);
if (searched == null || !_data.contains(searched)) {
return Center(
child: Text(
......@@ -228,26 +228,26 @@ class _SearchDemoSearchDelegate extends SearchDelegate<int> {
class _ResultCard extends StatelessWidget {
const _ResultCard({this.integer, this.title, this.searchDelegate});
final int integer;
final String title;
final SearchDelegate<int> searchDelegate;
final int? integer;
final String? title;
final SearchDelegate<int?>? searchDelegate;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return GestureDetector(
onTap: () {
searchDelegate.close(context, integer);
searchDelegate!.close(context, integer);
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Text(title),
Text(title!),
Text(
'$integer',
style: theme.textTheme.headline5.copyWith(fontSize: 72.0),
style: theme.textTheme.headline5!.copyWith(fontSize: 72.0),
),
],
),
......@@ -260,33 +260,33 @@ class _ResultCard extends StatelessWidget {
class _SuggestionList extends StatelessWidget {
const _SuggestionList({this.suggestions, this.query, this.onSelected});
final List<String> suggestions;
final String query;
final ValueChanged<String> onSelected;
final List<String>? suggestions;
final String? query;
final ValueChanged<String>? onSelected;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return ListView.builder(
itemCount: suggestions.length,
itemCount: suggestions!.length,
itemBuilder: (BuildContext context, int i) {
final String suggestion = suggestions[i];
final String suggestion = suggestions![i];
return ListTile(
leading: query.isEmpty ? const Icon(Icons.history) : const Icon(null),
leading: query!.isEmpty ? const Icon(Icons.history) : const Icon(null),
title: RichText(
text: TextSpan(
text: suggestion.substring(0, query.length),
style: theme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold),
text: suggestion.substring(0, query!.length),
style: theme.textTheme.subtitle1!.copyWith(fontWeight: FontWeight.bold),
children: <TextSpan>[
TextSpan(
text: suggestion.substring(query.length),
text: suggestion.substring(query!.length),
style: theme.textTheme.subtitle1,
),
],
),
),
onTap: () {
onSelected(suggestion);
onSelected!(suggestion);
},
);
},
......
......@@ -67,13 +67,13 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
);
}
bool checkboxValueA = true;
bool checkboxValueB = false;
bool checkboxValueC;
int radioValue = 0;
bool? checkboxValueA = true;
bool? checkboxValueB = false;
bool? checkboxValueC;
int? radioValue = 0;
bool switchValue = false;
void handleRadioValueChanged(int value) {
void handleRadioValueChanged(int? value) {
setState(() {
radioValue = value;
});
......@@ -92,7 +92,7 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
label: 'Checkbox A',
child: Checkbox(
value: checkboxValueA,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
checkboxValueA = value;
});
......@@ -103,7 +103,7 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
label: 'Checkbox B',
child: Checkbox(
value: checkboxValueB,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
checkboxValueB = value;
});
......@@ -115,7 +115,7 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
child: Checkbox(
value: checkboxValueC,
tristate: true,
onChanged: (bool value) {
onChanged: (bool? value) {
setState(() {
checkboxValueC = value;
});
......
......@@ -61,15 +61,15 @@ class _CustomRangeThumbShape extends RangeSliderThumbShape {
void paint(
PaintingContext context,
Offset center, {
@required Animation<double> activationAnimation,
@required Animation<double> enableAnimation,
required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
bool isDiscrete = false,
bool isEnabled = false,
bool isOnTop,
@required SliderThemeData sliderTheme,
TextDirection textDirection,
Thumb thumb,
bool isPressed,
bool? isOnTop,
required SliderThemeData sliderTheme,
TextDirection? textDirection,
Thumb? thumb,
bool? isPressed,
}) {
final Canvas canvas = context.canvas;
final ColorTween colorTween = ColorTween(
......@@ -78,7 +78,7 @@ class _CustomRangeThumbShape extends RangeSliderThumbShape {
);
final double size = _thumbSize * sizeTween.evaluate(enableAnimation);
Path thumbPath;
late Path thumbPath;
switch (textDirection) {
case TextDirection.rtl:
switch (thumb) {
......@@ -88,6 +88,8 @@ class _CustomRangeThumbShape extends RangeSliderThumbShape {
case Thumb.end:
thumbPath = _leftTriangle(size, center);
break;
default:
break;
}
break;
case TextDirection.ltr:
......@@ -98,10 +100,14 @@ class _CustomRangeThumbShape extends RangeSliderThumbShape {
case Thumb.end:
thumbPath = _rightTriangle(size, center);
break;
default:
break;
}
break;
default:
break;
}
canvas.drawPath(thumbPath, Paint()..color = colorTween.evaluate(enableAnimation));
canvas.drawPath(thumbPath, Paint()..color = colorTween.evaluate(enableAnimation)!);
}
}
......@@ -123,16 +129,16 @@ class _CustomThumbShape extends SliderComponentShape {
void paint(
PaintingContext context,
Offset thumbCenter, {
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
double textScaleFactor,
Size sizeWithOverflow,
Animation<double>? activationAnimation,
required Animation<double> enableAnimation,
bool? isDiscrete,
TextPainter? labelPainter,
RenderBox? parentBox,
required SliderThemeData sliderTheme,
TextDirection? textDirection,
double? value,
double? textScaleFactor,
Size? sizeWithOverflow,
}) {
final Canvas canvas = context.canvas;
final ColorTween colorTween = ColorTween(
......@@ -141,7 +147,7 @@ class _CustomThumbShape extends SliderComponentShape {
);
final double size = _thumbSize * sizeTween.evaluate(enableAnimation);
final Path thumbPath = _downTriangle(size, thumbCenter);
canvas.drawPath(thumbPath, Paint()..color = colorTween.evaluate(enableAnimation));
canvas.drawPath(thumbPath, Paint()..color = colorTween.evaluate(enableAnimation)!);
}
}
......@@ -164,16 +170,16 @@ class _CustomValueIndicatorShape extends SliderComponentShape {
void paint(
PaintingContext context,
Offset thumbCenter, {
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
double textScaleFactor,
Size sizeWithOverflow,
required Animation<double> activationAnimation,
required Animation<double> enableAnimation,
bool? isDiscrete,
required TextPainter labelPainter,
RenderBox? parentBox,
required SliderThemeData sliderTheme,
TextDirection? textDirection,
double? value,
double? textScaleFactor,
Size? sizeWithOverflow,
}) {
final Canvas canvas = context.canvas;
final ColorTween enableColor = ColorTween(
......@@ -187,7 +193,7 @@ class _CustomValueIndicatorShape extends SliderComponentShape {
final double size = _indicatorSize * sizeTween.evaluate(enableAnimation);
final Offset slideUpOffset = Offset(0.0, -slideUpTween.evaluate(activationAnimation));
final Path thumbPath = _upTriangle(size, thumbCenter + slideUpOffset);
final Color paintColor = enableColor.evaluate(enableAnimation).withAlpha((255.0 * activationAnimation.value).round());
final Color paintColor = enableColor.evaluate(enableAnimation)!.withAlpha((255.0 * activationAnimation.value).round());
canvas.drawPath(
thumbPath,
Paint()..color = paintColor,
......@@ -259,10 +265,10 @@ class _SlidersState extends State<_Sliders> {
child: TextField(
textAlign: TextAlign.center,
onSubmitted: (String value) {
final double newValue = double.tryParse(value);
final double? newValue = double.tryParse(value);
if (newValue != null && newValue != _continuousValue) {
setState(() {
_continuousValue = newValue.clamp(0.0, 100.0) as double;
_continuousValue = newValue.clamp(0.0, 100.0);
});
}
},
......@@ -326,7 +332,7 @@ class _SlidersState extends State<_Sliders> {
valueIndicatorColor: Colors.deepPurpleAccent,
thumbShape: _CustomThumbShape(),
valueIndicatorShape: _CustomValueIndicatorShape(),
valueIndicatorTextStyle: theme.accentTextTheme.bodyText1.copyWith(color: theme.colorScheme.onSurface),
valueIndicatorTextStyle: theme.accentTextTheme.bodyText1!.copyWith(color: theme.colorScheme.onSurface),
),
child: Slider(
value: _discreteCustomValue,
......
......@@ -19,7 +19,7 @@ const String _text3 =
'By default snackbars automatically disappear after a few seconds ';
class SnackBarDemo extends StatefulWidget {
const SnackBarDemo({ Key key }) : super(key: key);
const SnackBarDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/snack-bar';
......
......@@ -13,17 +13,17 @@ const String _kGalleryAssetsPackage = 'flutter_gallery_assets';
class _Page {
_Page({ this.label });
final String label;
String get id => label.characters.first;
final String? label;
String get id => label!.characters.first;
@override
String toString() => '$runtimeType("$label")';
}
class _CardData {
const _CardData({ this.title, this.imageAsset, this.imageAssetPackage });
final String title;
final String imageAsset;
final String imageAssetPackage;
final String? title;
final String? imageAsset;
final String? imageAssetPackage;
}
final Map<_Page, List<_CardData>> _allPages = <_Page, List<_CardData>>{
......@@ -97,8 +97,8 @@ class _CardDataItem extends StatelessWidget {
const _CardDataItem({ this.page, this.data });
static const double height = 272.0;
final _Page page;
final _CardData data;
final _Page? page;
final _CardData? data;
@override
Widget build(BuildContext context) {
......@@ -110,23 +110,23 @@ class _CardDataItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Align(
alignment: page.id == 'H'
alignment: page!.id == 'H'
? Alignment.centerLeft
: Alignment.centerRight,
child: CircleAvatar(child: Text(page.id)),
child: CircleAvatar(child: Text(page!.id)),
),
SizedBox(
width: 144.0,
height: 144.0,
child: Image.asset(
data.imageAsset,
package: data.imageAssetPackage,
data!.imageAsset!,
package: data!.imageAssetPackage,
fit: BoxFit.contain,
),
),
Center(
child: Text(
data.title,
data!.title!,
style: Theme.of(context).textTheme.headline6,
),
),
......@@ -187,7 +187,7 @@ class TabsDemo extends StatelessWidget {
itemExtent: _CardDataItem.height,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final _CardData data = _allPages[page][index];
final _CardData data = _allPages[page]![index];
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
......@@ -198,7 +198,7 @@ class TabsDemo extends StatelessWidget {
),
);
},
childCount: _allPages[page].length,
childCount: _allPages[page]!.length,
),
),
),
......
......@@ -15,13 +15,13 @@ const String _explanatoryText =
class _Page {
_Page({ this.label, this.colors, this.icon });
final String label;
final MaterialColor colors;
final IconData icon;
final String? label;
final MaterialColor? colors;
final IconData? icon;
Color get labelColor => colors != null ? colors.shade300 : Colors.grey.shade300;
Color get labelColor => colors != null ? colors!.shade300 : Colors.grey.shade300;
bool get fabDefined => colors != null && icon != null;
Color get fabColor => colors.shade400;
Color get fabColor => colors!.shade400;
Icon get fabIcon => Icon(icon);
Key get fabKey => ValueKey<Color>(fabColor);
}
......@@ -44,32 +44,32 @@ class TabsFabDemo extends StatefulWidget {
class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStateMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _controller;
_Page _selectedPage;
TabController? _controller;
late _Page _selectedPage;
bool _extendedButtons = false;
@override
void initState() {
super.initState();
_controller = TabController(vsync: this, length: _allPages.length);
_controller.addListener(_handleTabSelection);
_controller!.addListener(_handleTabSelection);
_selectedPage = _allPages[0];
}
@override
void dispose() {
_controller.dispose();
_controller!.dispose();
super.dispose();
}
void _handleTabSelection() {
setState(() {
_selectedPage = _allPages[_controller.index];
_selectedPage = _allPages[_controller!.index];
});
}
void _showExplanatoryText() {
_scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) {
_scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(top: BorderSide(color: Theme.of(context).dividerColor))
......@@ -86,11 +86,11 @@ class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStat
return Builder(
builder: (BuildContext context) {
return Container(
key: ValueKey<String>(page.label),
key: ValueKey<String?>(page.label),
padding: const EdgeInsets.fromLTRB(48.0, 48.0, 48.0, 96.0),
child: Card(
child: Center(
child: Text(page.label,
child: Text(page.label!,
style: TextStyle(
color: page.labelColor,
fontSize: 32.0,
......@@ -104,7 +104,7 @@ class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStat
);
}
Widget buildFloatingActionButton(_Page page) {
Widget? buildFloatingActionButton(_Page page) {
if (!page.fabDefined)
return null;
......@@ -114,7 +114,7 @@ class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStat
tooltip: 'Show explanation',
backgroundColor: page.fabColor,
icon: page.fabIcon,
label: Text(page.label.toUpperCase()),
label: Text(page.label!.toUpperCase()),
onPressed: _showExplanatoryText,
);
}
......@@ -136,7 +136,7 @@ class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStat
title: const Text('FAB per tab'),
bottom: TabBar(
controller: _controller,
tabs: _allPages.map<Widget>((_Page page) => Tab(text: page.label.toUpperCase())).toList(),
tabs: _allPages.map<Widget>((_Page page) => Tab(text: page.label!.toUpperCase())).toList(),
),
actions: <Widget>[
MaterialDemoDocumentationButton(TabsFabDemo.routeName),
......
......@@ -9,7 +9,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior;
import '../../gallery/demo.dart';
class TextFormFieldDemo extends StatefulWidget {
const TextFormFieldDemo({ Key key }) : super(key: key);
const TextFormFieldDemo({ Key? key }) : super(key: key);
static const String routeName = '/material/text-form-field';
......@@ -18,9 +18,9 @@ class TextFormFieldDemo extends StatefulWidget {
}
class PersonData {
String name = '';
String phoneNumber = '';
String email = '';
String? name = '';
String? phoneNumber = '';
String? email = '';
String password = '';
}
......@@ -35,13 +35,13 @@ class PasswordField extends StatefulWidget {
this.onFieldSubmitted,
});
final Key fieldKey;
final String hintText;
final String labelText;
final String helperText;
final FormFieldSetter<String> onSaved;
final FormFieldValidator<String> validator;
final ValueChanged<String> onFieldSubmitted;
final Key? fieldKey;
final String? hintText;
final String? labelText;
final String? helperText;
final FormFieldSetter<String>? onSaved;
final FormFieldValidator<String>? validator;
final ValueChanged<String>? onFieldSubmitted;
@override
_PasswordFieldState createState() => _PasswordFieldState();
......@@ -99,7 +99,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
final GlobalKey<FormFieldState<String>> _passwordFieldKey = GlobalKey<FormFieldState<String>>();
final _UsNumberTextInputFormatter _phoneNumberFormatter = _UsNumberTextInputFormatter();
void _handleSubmitted() {
final FormState form = _formKey.currentState;
final FormState form = _formKey.currentState!;
if (!form.validate()) {
_autovalidateMode = AutovalidateMode.always; // Start validating on every change.
showInSnackBar('Please fix the errors in red before submitting.');
......@@ -109,9 +109,9 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
}
}
String _validateName(String value) {
String? _validateName(String? value) {
_formWasEdited = true;
if (value.isEmpty)
if (value!.isEmpty)
return 'Name is required.';
final RegExp nameExp = RegExp(r'^[A-Za-z ]+$');
if (!nameExp.hasMatch(value))
......@@ -119,18 +119,18 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
return null;
}
String _validatePhoneNumber(String value) {
String? _validatePhoneNumber(String? value) {
_formWasEdited = true;
final RegExp phoneExp = RegExp(r'^\(\d\d\d\) \d\d\d\-\d\d\d\d$');
if (!phoneExp.hasMatch(value))
if (!phoneExp.hasMatch(value!))
return '(###) ###-#### - Enter a US phone number.';
return null;
}
String _validatePassword(String value) {
String? _validatePassword(String? value) {
_formWasEdited = true;
final FormFieldState<String> passwordField = _passwordFieldKey.currentState;
if (passwordField.value == null || passwordField.value.isEmpty)
final FormFieldState<String> passwordField = _passwordFieldKey.currentState!;
if (passwordField.value == null || passwordField.value!.isEmpty)
return 'Please enter a password.';
if (passwordField.value != value)
return "The passwords don't match";
......@@ -138,11 +138,11 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
}
Future<bool> _warnUserAboutInvalidData() async {
final FormState form = _formKey.currentState;
final FormState? form = _formKey.currentState;
if (form == null || !_formWasEdited || form.validate())
return true;
return await showDialog<bool>(
return await (showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
......@@ -151,16 +151,16 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
actions: <Widget> [
TextButton(
child: const Text('YES'),
onPressed: () { Navigator.of(context).pop(true); },
onPressed: () { Navigator.of(context)!.pop(true); },
),
TextButton(
child: const Text('NO'),
onPressed: () { Navigator.of(context).pop(false); },
onPressed: () { Navigator.of(context)!.pop(false); },
),
],
);
},
) ?? false;
) as Future<bool>);
}
@override
......@@ -195,7 +195,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
hintText: 'What do people call you?',
labelText: 'Name *',
),
onSaved: (String value) { person.name = value; },
onSaved: (String? value) { person.name = value; },
validator: _validateName,
),
const SizedBox(height: 24.0),
......@@ -209,7 +209,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
prefixText: '+1',
),
keyboardType: TextInputType.phone,
onSaved: (String value) { person.phoneNumber = value; },
onSaved: (String? value) { person.phoneNumber = value; },
validator: _validatePhoneNumber,
// TextInputFormatters are applied in sequence.
inputFormatters: <TextInputFormatter> [
......@@ -228,7 +228,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
labelText: 'E-mail',
),
keyboardType: TextInputType.emailAddress,
onSaved: (String value) { person.email = value; },
onSaved: (String? value) { person.email = value; },
),
const SizedBox(height: 24.0),
TextFormField(
......@@ -265,7 +265,7 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
),
const SizedBox(height: 24.0),
TextFormField(
enabled: person.password != null && person.password.isNotEmpty,
enabled: person.password.isNotEmpty,
decoration: const InputDecoration(
border: UnderlineInputBorder(),
filled: true,
......
......@@ -20,7 +20,7 @@ class ShrineApp extends StatefulWidget {
class _ShrineAppState extends State<ShrineApp> with SingleTickerProviderStateMixin {
// Controller to coordinate both the opening/closing of backdrop and sliding
// of expanding bottom sheet
AnimationController _controller;
late AnimationController _controller;
@override
void initState() {
......@@ -55,7 +55,7 @@ class _ShrineAppState extends State<ShrineApp> with SingleTickerProviderStateMix
}
}
Route<dynamic> _getRoute(RouteSettings settings) {
Route<dynamic>? _getRoute(RouteSettings settings) {
if (settings.name != '/login') {
return null;
}
......@@ -98,11 +98,11 @@ ThemeData _buildShrineTheme() {
TextTheme _buildShrineTextTheme(TextTheme base) {
return base.copyWith(
headline5: base.headline5.copyWith(fontWeight: FontWeight.w500),
headline6: base.headline6.copyWith(fontSize: 18.0),
caption: base.caption.copyWith(fontWeight: FontWeight.w400, fontSize: 14.0),
bodyText1: base.bodyText1.copyWith(fontWeight: FontWeight.w500, fontSize: 16.0),
button: base.button.copyWith(fontWeight: FontWeight.w500, fontSize: 14.0),
headline5: base.headline5!.copyWith(fontWeight: FontWeight.w500),
headline6: base.headline6!.copyWith(fontSize: 18.0),
caption: base.caption!.copyWith(fontWeight: FontWeight.w400, fontSize: 14.0),
bodyText1: base.bodyText1!.copyWith(fontWeight: FontWeight.w500, fontSize: 16.0),
button: base.button!.copyWith(fontWeight: FontWeight.w500, fontSize: 14.0),
).apply(
fontFamily: 'Raleway',
displayColor: kShrineBrown900,
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:flutter_gallery/demo/shrine/login.dart';
......@@ -15,37 +14,37 @@ const double _kPeakVelocityProgress = 0.379146;
class _TappableWhileStatusIs extends StatefulWidget {
const _TappableWhileStatusIs(
this.status, {
Key key,
Key? key,
this.controller,
this.child,
}) : super(key: key);
final AnimationController controller;
final AnimationController? controller;
final AnimationStatus status;
final Widget child;
final Widget? child;
@override
_TappableWhileStatusIsState createState() => _TappableWhileStatusIsState();
}
class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
bool _active;
bool? _active;
@override
void initState() {
super.initState();
widget.controller.addStatusListener(_handleStatusChange);
_active = widget.controller.status == widget.status;
widget.controller!.addStatusListener(_handleStatusChange);
_active = widget.controller!.status == widget.status;
}
@override
void dispose() {
widget.controller.removeStatusListener(_handleStatusChange);
widget.controller!.removeStatusListener(_handleStatusChange);
super.dispose();
}
void _handleStatusChange(AnimationStatus status) {
final bool value = widget.controller.status == widget.status;
final bool value = widget.controller!.status == widget.status;
if (_active != value) {
setState(() {
_active = value;
......@@ -56,11 +55,11 @@ class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
@override
Widget build(BuildContext context) {
Widget child = AbsorbPointer(
absorbing: !_active,
absorbing: !_active!,
child: widget.child,
);
if (!_active) {
if (!_active!) {
child = FocusScope(
canRequestFocus: false,
debugLabel: '$_TappableWhileStatusIs',
......@@ -73,13 +72,13 @@ class _TappableWhileStatusIsState extends State<_TappableWhileStatusIs> {
class _FrontLayer extends StatelessWidget {
const _FrontLayer({
Key key,
Key? key,
this.onTap,
this.child,
}) : super(key: key);
final VoidCallback onTap;
final Widget child;
final VoidCallback? onTap;
final Widget? child;
@override
Widget build(BuildContext context) {
......@@ -100,7 +99,7 @@ class _FrontLayer extends StatelessWidget {
),
),
Expanded(
child: child,
child: child!,
),
],
),
......@@ -110,16 +109,14 @@ class _FrontLayer extends StatelessWidget {
class _BackdropTitle extends AnimatedWidget {
const _BackdropTitle({
Key key,
Animation<double> listenable,
Key? key,
required Animation<double> listenable,
this.onPress,
@required this.frontTitle,
@required this.backTitle,
}) : assert(frontTitle != null),
assert(backTitle != null),
super(key: key, listenable: listenable);
required this.frontTitle,
required this.backTitle,
}) : super(key: key, listenable: listenable);
final void Function() onPress;
final void Function()? onPress;
final Widget frontTitle;
final Widget backTitle;
......@@ -131,7 +128,7 @@ class _BackdropTitle extends AnimatedWidget {
);
return DefaultTextStyle(
style: Theme.of(context).primaryTextTheme.headline6,
style: Theme.of(context).primaryTextTheme.headline6!,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: Row(children: <Widget>[
......@@ -201,16 +198,12 @@ class _BackdropTitle extends AnimatedWidget {
/// front or back layer is showing.
class Backdrop extends StatefulWidget {
const Backdrop({
@required this.frontLayer,
@required this.backLayer,
@required this.frontTitle,
@required this.backTitle,
@required this.controller,
}) : assert(frontLayer != null),
assert(backLayer != null),
assert(frontTitle != null),
assert(backTitle != null),
assert(controller != null);
required this.frontLayer,
required this.backLayer,
required this.frontTitle,
required this.backTitle,
required this.controller,
});
final Widget frontLayer;
final Widget backLayer;
......@@ -224,8 +217,8 @@ class Backdrop extends StatefulWidget {
class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin {
final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');
AnimationController _controller;
Animation<RelativeRect> _layerAnimation;
AnimationController? _controller;
late Animation<RelativeRect> _layerAnimation;
@override
void initState() {
......@@ -235,19 +228,19 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
@override
void dispose() {
_controller.dispose();
_controller!.dispose();
super.dispose();
}
bool get _frontLayerVisible {
final AnimationStatus status = _controller.status;
final AnimationStatus status = _controller!.status;
return status == AnimationStatus.completed || status == AnimationStatus.forward;
}
void _toggleBackdropLayerVisibility() {
// Call setState here to update layerAnimation if that's necessary
setState(() {
_frontLayerVisible ? _controller.reverse() : _controller.forward();
_frontLayerVisible ? _controller!.reverse() : _controller!.forward();
});
}
......@@ -267,7 +260,7 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
firstWeight = _kPeakVelocityTime;
secondWeight = 1.0 - _kPeakVelocityTime;
animation = CurvedAnimation(
parent: _controller.view,
parent: _controller!.view,
curve: const Interval(0.0, 0.78),
);
} else {
......@@ -276,7 +269,7 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
secondCurve = _kAccelerateCurve.flipped;
firstWeight = 1.0 - _kPeakVelocityTime;
secondWeight = _kPeakVelocityTime;
animation = _controller.view;
animation = _controller!.view;
}
return TweenSequence<RelativeRect>(
......@@ -351,7 +344,7 @@ class _BackdropState extends State<Backdrop> with SingleTickerProviderStateMixin
elevation: 0.0,
titleSpacing: 0.0,
title: _BackdropTitle(
listenable: _controller.view,
listenable: _controller!.view,
onPress: _toggleBackdropLayerVisibility,
frontTitle: widget.frontTitle,
backTitle: widget.backTitle,
......
......@@ -11,22 +11,22 @@ import 'package:flutter_gallery/demo/shrine/model/product.dart';
class CategoryMenuPage extends StatelessWidget {
const CategoryMenuPage({
Key key,
Key? key,
this.onCategoryTap,
}) : super(key: key);
final VoidCallback onCategoryTap;
final VoidCallback? onCategoryTap;
Widget _buildCategory(Category category, BuildContext context) {
final String categoryString = category.toString().replaceAll('Category.', '').toUpperCase();
final ThemeData theme = Theme.of(context);
return ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context, Widget child, AppStateModel model) =>
builder: (BuildContext context, Widget? child, AppStateModel model) =>
GestureDetector(
onTap: () {
model.setCategory(category);
if (onCategoryTap != null) {
onCategoryTap();
onCategoryTap!();
}
},
child: model.selectedCategory == category
......@@ -50,7 +50,7 @@ class CategoryMenuPage extends StatelessWidget {
padding: const 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,
......
......@@ -4,7 +4,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:flutter_gallery/demo/shrine/colors.dart';
......@@ -26,19 +25,16 @@ const double _kCornerRadius = 24.0;
const double _kWidthForCartIcon = 64.0;
class ExpandingBottomSheet extends StatefulWidget {
const ExpandingBottomSheet({Key key, @required this.hideController})
: assert(hideController != null),
super(key: key);
const ExpandingBottomSheet({Key? key, required this.hideController})
: super(key: key);
final AnimationController hideController;
@override
_ExpandingBottomSheetState createState() => _ExpandingBottomSheetState();
static _ExpandingBottomSheetState of(BuildContext context, {bool isNullOk = false}) {
assert(isNullOk != null);
assert(context != null);
final _ExpandingBottomSheetState result = context.findAncestorStateOfType<_ExpandingBottomSheetState>();
static _ExpandingBottomSheetState? of(BuildContext context, {bool isNullOk = false}) {
final _ExpandingBottomSheetState? result = context.findAncestorStateOfType<_ExpandingBottomSheetState>();
if (isNullOk || result != null) {
return result;
}
......@@ -53,11 +49,11 @@ class ExpandingBottomSheet extends StatefulWidget {
// curve formula. It's quintic, not cubic. But it _can_ be expressed as one
// curve followed by another, which we do here.
Animation<T> _getEmphasizedEasingAnimation<T>({
@required T begin,
@required T peak,
@required T end,
@required bool isForward,
@required Animation<double> parent,
required T begin,
required T peak,
required T end,
required bool isForward,
required Animation<double> parent,
}) {
Curve firstCurve;
Curve secondCurve;
......@@ -98,7 +94,7 @@ Animation<T> _getEmphasizedEasingAnimation<T>({
// Calculates the value where two double Animations should be joined. Used by
// callers of _getEmphasisedEasing<double>().
double _getPeakPoint({double begin, double end}) {
double _getPeakPoint({required double begin, required double end}) {
return begin + (end - begin) * _kPeakVelocityProgress;
}
......@@ -111,15 +107,15 @@ class _ExpandingBottomSheetState extends State<ExpandingBottomSheet> with Ticker
double _width = _kWidthForCartIcon;
// Controller for the opening and closing of the ExpandingBottomSheet
AnimationController _controller;
late AnimationController _controller;
// Animations for the opening and closing of the ExpandingBottomSheet
Animation<double> _widthAnimation;
Animation<double> _heightAnimation;
Animation<double> _thumbnailOpacityAnimation;
Animation<double> _cartOpacityAnimation;
Animation<double> _shapeAnimation;
Animation<Offset> _slideAnimation;
late Animation<double> _widthAnimation;
late Animation<double> _heightAnimation;
late Animation<double> _thumbnailOpacityAnimation;
late Animation<double> _cartOpacityAnimation;
late Animation<double> _shapeAnimation;
late Animation<Offset> _slideAnimation;
@override
void initState() {
......@@ -308,7 +304,7 @@ class _ExpandingBottomSheetState extends State<ExpandingBottomSheet> with Ticker
);
}
Widget _buildCart(BuildContext context, Widget child) {
Widget _buildCart(BuildContext context, Widget? child) {
// numProducts is the number of different products in the cart (does not
// include multiples of the same product).
final AppStateModel model = ScopedModel.of<AppStateModel>(context);
......@@ -349,7 +345,7 @@ class _ExpandingBottomSheetState extends State<ExpandingBottomSheet> with Ticker
}
// Builder for the hide and reveal animation when the backdrop opens and closes
Widget _buildSlideAnimation(BuildContext context, Widget child) {
Widget _buildSlideAnimation(BuildContext context, Widget? child) {
_slideAnimation = _getEmphasizedEasingAnimation(
begin: const Offset(1.0, 0.0),
peak: const Offset(_kPeakVelocityProgress, 0.0),
......@@ -393,7 +389,7 @@ class _ExpandingBottomSheetState extends State<ExpandingBottomSheet> with Ticker
behavior: HitTestBehavior.opaque,
onTap: open,
child: ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context, Widget child, AppStateModel model) {
builder: (BuildContext context, Widget? child, AppStateModel model) {
return AnimatedBuilder(
builder: _buildCart,
animation: _controller,
......@@ -417,10 +413,10 @@ class _ProductThumbnailRowState extends State<ProductThumbnailRow> {
// _list represents what's currently on screen. If _internalList updates,
// it will need to be updated to match it.
_ListModel _list;
late _ListModel _list;
// _internalList represents the list as it is updated by the AppStateModel.
List<int> _internalList;
late List<int> _internalList;
@override
void initState() {
......@@ -436,7 +432,6 @@ class _ProductThumbnailRowState extends State<ProductThumbnailRow> {
Product _productWithId(int productId) {
final AppStateModel model = ScopedModel.of<AppStateModel>(context);
final Product product = model.getProductById(productId);
assert(product != null);
return product;
}
......@@ -510,7 +505,7 @@ class _ProductThumbnailRowState extends State<ProductThumbnailRow> {
Widget build(BuildContext context) {
_updateLists();
return ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context, Widget child, AppStateModel model) => _buildAnimatedList(),
builder: (BuildContext context, Widget? child, AppStateModel model) => _buildAnimatedList(),
);
}
}
......@@ -529,7 +524,7 @@ class ExtraProductsNumber extends StatelessWidget {
final int numProducts = products.length;
if (numProducts > 3) {
for (int i = 3; i < numProducts; i++) {
overflow += productMap[products[i]];
overflow += productMap[products[i]]!;
}
}
return overflow;
......@@ -553,7 +548,7 @@ class ExtraProductsNumber extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<AppStateModel>(
builder: (BuildContext builder, Widget child, AppStateModel model) => _buildOverflow(model, context),
builder: (BuildContext builder, Widget? child, AppStateModel model) => _buildOverflow(model, context),
);
}
}
......@@ -594,18 +589,16 @@ class ProductThumbnail extends StatelessWidget {
// _ListModel manipulates an internal list and an AnimatedList
class _ListModel {
_ListModel({
@required this.listKey,
@required this.removedItemBuilder,
Iterable<int> initialItems,
}) : assert(listKey != null),
assert(removedItemBuilder != null),
_items = initialItems?.toList() ?? <int>[];
required this.listKey,
required this.removedItemBuilder,
Iterable<int>? initialItems,
}) : _items = initialItems?.toList() ?? <int>[];
final GlobalKey<AnimatedListState> listKey;
final Widget Function(int item, BuildContext context, Animation<double> animation) removedItemBuilder;
final List<int> _items;
AnimatedListState get _animatedList => listKey.currentState;
AnimatedListState? get _animatedList => listKey.currentState;
void add(int product) {
_insert(_items.length, product);
......@@ -613,7 +606,7 @@ class _ListModel {
void _insert(int index, int item) {
_items.insert(index, item);
_animatedList.insertItem(index, duration: const Duration(milliseconds: 225));
_animatedList!.insertItem(index, duration: const Duration(milliseconds: 225));
}
void remove(int product) {
......@@ -625,12 +618,10 @@ class _ListModel {
void _removeAt(int index) {
final int removedItem = _items.removeAt(index);
if (removedItem != null) {
_animatedList.removeItem(index, (BuildContext context, Animation<double> animation) {
_animatedList!.removeItem(index, (BuildContext context, Animation<double> animation) {
return removedItemBuilder(removedItem, context, animation);
});
}
}
int get length => _items.length;
......
......@@ -19,7 +19,7 @@ class ProductPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<AppStateModel>(
builder: (BuildContext context, Widget child, AppStateModel model) {
builder: (BuildContext context, Widget? child, AppStateModel model) {
return AsymmetricView(products: model.getProducts());
});
}
......@@ -29,17 +29,18 @@ class HomePage extends StatelessWidget {
const HomePage({
this.expandingBottomSheet,
this.backdrop,
Key key,
Key? key,
}) : super(key: key);
final ExpandingBottomSheet expandingBottomSheet;
final Backdrop backdrop;
final ExpandingBottomSheet? expandingBottomSheet;
final Backdrop? backdrop;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
backdrop,
if (backdrop != null)
backdrop!,
Align(child: expandingBottomSheet, alignment: Alignment.bottomRight),
],
);
......
......@@ -35,7 +35,7 @@ class _LoginPageState extends State<LoginPage> {
// The login screen is immediately displayed on top of the Shrine
// home screen using onGenerateRoute and so rootNavigator must be
// set to true in order to get out of Shrine completely.
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context, rootNavigator: true)!.pop();
},
),
),
......@@ -95,7 +95,7 @@ class _LoginPageState extends State<LoginPage> {
// the Shrine home screen using onGenerateRoute and so
// rootNavigator must be set to true in order to get out
// of Shrine completely.
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context, rootNavigator: true)!.pop();
},
child: const Text('CANCEL'),
),
......@@ -123,15 +123,15 @@ class _LoginPageState extends State<LoginPage> {
}
class PrimaryColorOverride extends StatelessWidget {
const PrimaryColorOverride({Key key, this.color, this.child}) : super(key: key);
const PrimaryColorOverride({Key? key, this.color, this.child}) : super(key: key);
final Color color;
final Widget child;
final Color? color;
final Widget? child;
@override
Widget build(BuildContext context) {
return Theme(
child: child,
child: child!,
data: Theme.of(context).copyWith(primaryColor: color),
);
}
......
......@@ -12,7 +12,7 @@ double _shippingCostPerItem = 7.0;
class AppStateModel extends Model {
// All the available products.
List<Product> _availableProducts;
List<Product>? _availableProducts;
// The currently selected category of products.
Category _selectedCategory = Category.all;
......@@ -30,7 +30,7 @@ class AppStateModel extends Model {
// Totaled prices of the items in the cart.
double get subtotalCost {
return _productsInCart.keys
.map((int id) => _availableProducts[id].price * _productsInCart[id])
.map((int id) => _availableProducts![id].price * _productsInCart[id]!)
.fold(0.0, (double sum, int e) => sum + e);
}
......@@ -52,9 +52,9 @@ class AppStateModel extends Model {
}
if (_selectedCategory == Category.all) {
return List<Product>.from(_availableProducts);
return List<Product>.from(_availableProducts!);
} else {
return _availableProducts
return _availableProducts!
.where((Product p) => p.category == _selectedCategory)
.toList();
}
......@@ -62,10 +62,11 @@ class AppStateModel extends Model {
// Adds a product to the cart.
void addProductToCart(int productId) {
if (!_productsInCart.containsKey(productId)) {
final int? value = _productsInCart[productId];
if (value == null) {
_productsInCart[productId] = 1;
} else {
_productsInCart[productId]++;
_productsInCart[productId] = value+1;
}
notifyListeners();
......@@ -73,11 +74,13 @@ class AppStateModel extends Model {
// Removes an item from the cart.
void removeItemFromCart(int productId) {
if (_productsInCart.containsKey(productId)) {
final int? value = _productsInCart[productId];
if (value != null) {
if (_productsInCart[productId] == 1) {
_productsInCart.remove(productId);
} else {
_productsInCart[productId]--;
_productsInCart[productId] = value - 1;
}
}
......@@ -86,7 +89,7 @@ class AppStateModel extends Model {
// Returns the Product instance matching the provided id.
Product getProductById(int id) {
return _availableProducts.firstWhere((Product p) => p.id == id);
return _availableProducts!.firstWhere((Product p) => p.id == id);
}
// Removes everything from the cart.
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
enum Category {
all,
accessories,
......@@ -13,16 +11,12 @@ enum Category {
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;
......
......@@ -8,12 +8,12 @@ import 'package:flutter_gallery/demo/shrine/model/product.dart';
import 'package:flutter_gallery/demo/shrine/supplemental/product_columns.dart';
class AsymmetricView extends StatelessWidget {
const AsymmetricView({Key key, this.products}) : super(key: key);
const AsymmetricView({Key? key, this.products}) : super(key: key);
final List<Product> products;
final List<Product>? products;
List<Container> _buildColumns(BuildContext context) {
if (products == null || products.isEmpty) {
if (products == null || products!.isEmpty) {
return const <Container>[];
}
......@@ -25,23 +25,23 @@ class AsymmetricView extends StatelessWidget {
// some kinda awkward math so we use _evenCasesIndex and _oddCasesIndex as
// helpers for creating the index of the product list that will correspond
// to the index of the list of columns.
return List<Container>.generate(_listItemCount(products.length), (int index) {
return List<Container>.generate(_listItemCount(products!.length), (int index) {
double width = .59 * MediaQuery.of(context).size.width;
Widget column;
if (index.isEven) {
/// Even cases
final int bottom = _evenCasesIndex(index);
column = TwoProductCardColumn(
bottom: products[bottom],
top: products.length - 1 >= bottom + 1
? products[bottom + 1]
bottom: products![bottom],
top: products!.length - 1 >= bottom + 1
? products![bottom + 1]
: null,
);
width += 32.0;
} else {
/// Odd cases
column = OneProductCardColumn(
product: products[_oddCasesIndex(index)],
product: products![_oddCasesIndex(index)],
);
}
return Container(
......
......@@ -9,11 +9,11 @@ import 'package:flutter_gallery/demo/shrine/supplemental/product_card.dart';
class TwoProductCardColumn extends StatelessWidget {
const TwoProductCardColumn({
@required this.bottom,
required this.bottom,
this.top,
}) : assert(bottom != null);
});
final Product bottom, top;
final Product? bottom, top;
@override
Widget build(BuildContext context) {
......@@ -59,7 +59,7 @@ class TwoProductCardColumn extends StatelessWidget {
class OneProductCardColumn extends StatelessWidget {
const OneProductCardColumn({this.product});
final Product product;
final Product? product;
@override
Widget build(BuildContext context) {
......
......@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gallery/demo/shrine/app.dart';
class ShrineDemo extends StatelessWidget {
const ShrineDemo({ Key key }) : super(key: key);
const ShrineDemo({ Key? key }) : super(key: key);
static const String routeName = '/shrine'; // Used by the Gallery app.
......
......@@ -60,7 +60,7 @@ class InertialMotion {
// Solve the equation of motion to find the position at a given point in time
// in one dimension.
double _getPosition({double r0, double v0, int t, double a}) {
double _getPosition({required double r0, required double v0, required int t, required double a}) {
// Stop movement when it would otherwise reverse direction.
final double stopTime = (v0 / a).abs();
if (t > stopTime) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment