diff --git a/analysis_options.yaml b/analysis_options.yaml index ba114a26..91075908 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,6 +3,8 @@ include: package:lint/analysis_options.yaml analyzer: exclude: - build/** + - "lib/**/*.g.dart" + - "lib/**/*.freezed.dart" enable-experiment: - non-nullable @@ -20,4 +22,6 @@ linter: use_string_buffers: false avoid_redundant_argument_values: false prefer_const_constructors: false - avoid_dynamic_calls: false \ No newline at end of file + avoid_dynamic_calls: false + directives_ordering: false + sort_pub_dependencies: false \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 63663905..ed0f5f0d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { applicationId "io.github.x_wei.flutter_catalog" - minSdkVersion 16 + minSdkVersion 21 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -99,11 +99,6 @@ dependencies { implementation 'com.google.firebase:firebase-analytics:17.5.0' implementation 'com.google.firebase:firebase-auth:19.4.0' implementation 'com.google.firebase:firebase-firestore:21.6.0' - // Cf. https://firebase.google.com/docs/ml-kit/android/read-barcodes. - implementation 'com.google.firebase:firebase-ml-vision:24.0.3' - implementation 'com.google.firebase:firebase-ml-vision-barcode-model:16.0.1' - implementation 'com.google.firebase:firebase-ml-vision-image-label-model:20.0.1' - implementation 'com.google.firebase:firebase-ml-vision-face-model:20.0.1' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 95dd0e91..3e32ad2d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -28,8 +28,8 @@ + android:name="com.google.mlkit.vision.DEPENDENCIES" + android:value="ocr,ica,barcode,face" /> diff --git a/lib/generated_plugin_registrant.dart b/lib/generated_plugin_registrant.dart index 875c05fa..8baabd84 100644 --- a/lib/generated_plugin_registrant.dart +++ b/lib/generated_plugin_registrant.dart @@ -12,6 +12,7 @@ import 'package:firebase_core_web/firebase_core_web.dart'; import 'package:firebase_storage_web/firebase_storage_web.dart'; import 'package:fluttertoast/fluttertoast_web.dart'; import 'package:google_sign_in_web/google_sign_in_web.dart'; +import 'package:image_picker_for_web/image_picker_for_web.dart'; import 'package:shared_preferences_web/shared_preferences_web.dart'; import 'package:url_launcher_web/url_launcher_web.dart'; import 'package:video_player_web/video_player_web.dart'; @@ -27,6 +28,7 @@ void registerPlugins(Registrar registrar) { FirebaseStorageWeb.registerWith(registrar); FluttertoastWebPlugin.registerWith(registrar); GoogleSignInPlugin.registerWith(registrar); + ImagePickerPlugin.registerWith(registrar); SharedPreferencesPlugin.registerWith(registrar); UrlLauncherPlugin.registerWith(registrar); VideoPlayerPlugin.registerWith(registrar); diff --git a/lib/home_page.dart b/lib/home_page.dart index 5d5ae2cf..ca0cfd94 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -9,7 +9,7 @@ import './my_app_settings.dart'; import './my_route.dart'; class MyHomePage extends StatefulWidget { - const MyHomePage({Key key}) : super(key: key); + const MyHomePage({Key? key}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); @@ -73,11 +73,11 @@ class _MyHomePageState extends State { } Widget _myRouteToListTile(MyRoute myRoute, - {Widget leading, IconData trialing = Icons.keyboard_arrow_right}) { + {Widget? leading, IconData trialing = Icons.keyboard_arrow_right}) { final mySettings = context.watch(); final routeTitleTextStyle = Theme.of(context) .textTheme - .bodyText2 + .bodyText2! .copyWith(fontWeight: FontWeight.bold); final leadingWidget = leading ?? mySettings.starStatusOfRoute(myRoute.routeName); @@ -90,8 +90,8 @@ class _MyHomePageState extends State { ) : leadingWidget, title: Text(myRoute.title, style: routeTitleTextStyle), - trailing: trialing == null ? null : Icon(trialing), - subtitle: myRoute.description == null ? null : Text(myRoute.description), + trailing: Icon(trialing), + subtitle: myRoute.description.isEmpty ? null : Text(myRoute.description), onTap: () { if (isNew) { mySettings.markRouteKnown(myRoute.routeName); diff --git a/lib/my_app_routes.dart b/lib/my_app_routes.dart index 934d1394..0f5e1336 100644 --- a/lib/my_app_routes.dart +++ b/lib/my_app_routes.dart @@ -45,7 +45,6 @@ import 'routes/layouts_fractionally_sizedbox_ex.dart'; import 'routes/layouts_row_col_ex.dart'; import 'routes/layouts_stack_ex.dart'; import 'routes/layouts_wrap_ex.dart'; -import 'routes/lists_wheel_scroll_view_ex.dart'; import 'routes/lists_datatable_ex.dart'; import 'routes/lists_expansion_tile_ex.dart'; import 'routes/lists_grid_list_ex.dart'; @@ -54,6 +53,7 @@ import 'routes/lists_listview_builder_ex.dart'; import 'routes/lists_reorderable_ex.dart'; import 'routes/lists_slidable_tile_ex.dart'; import 'routes/lists_swipe_to_dismiss_ex.dart'; +import 'routes/lists_wheel_scroll_view_ex.dart'; import 'routes/multimedia_edge_detection_ex.dart'; import 'routes/multimedia_extended_image_ex.dart'; import 'routes/multimedia_image_picker_ex.dart'; @@ -133,7 +133,7 @@ const kAboutRoute = MyRoute( // ] class MyRouteGroup { const MyRouteGroup( - {@required this.groupName, @required this.icon, @required this.routes}); + {required this.groupName, required this.icon, required this.routes}); final String groupName; final Widget icon; final List routes; @@ -363,14 +363,15 @@ const kMyAppRoutesBasic = [ ), MyRoute( sourceFilePath: 'lib/routes/lists_wheel_scroll_view_ex.dart', - child: ListWheelViewExample(), + child: ListWheelViewExample(), title: 'List Wheel Scroll View', description: 'fancy list view', links: { - 'Doc': 'https://api.flutter.dev/flutter/widgets/ListWheelScrollView-class.html', - 'Youtube':'https://youtu.be/dUhmWAz4C7Y' + 'Doc': + 'https://api.flutter.dev/flutter/widgets/ListWheelScrollView-class.html', + 'Youtube': 'https://youtu.be/dUhmWAz4C7Y' }, - ), + ), MyRoute( child: SlidableTileExample(), sourceFilePath: 'lib/routes/lists_slidable_tile_ex.dart', @@ -672,9 +673,7 @@ const kMyAppRoutesAdvanced = [ sourceFilePath: 'lib/routes/animation_animated_radial_menu_ex.dart', title: 'Animated Radial Menu', description: 'Easy add radial menu with high-quality animation', - links: { - 'Pub package': 'https://pub.dev/packages/animated_radial_menu' - }, + links: {'Pub package': 'https://pub.dev/packages/animated_radial_menu'}, ), MyRoute( child: LottieExample(), @@ -1058,12 +1057,14 @@ const kMyAppRoutesAdvanced = [ }, ), MyRoute( - child: FirebaseMLKitExample(), + child: GoogleMLKitExample(), sourceFilePath: 'lib/routes/firebase_mlkit_ex.dart', - title: 'Firebase ML Kit', + title: 'Google ML Kit', description: 'Image labelling, text OCR, barcode scan, face detection.', links: { - 'Doc': 'https://pub.dartlang.org/packages/firebase_ml_vision', + 'pub.dev': 'https://pub.dev/packages/google_ml_kit', + 'MLKit doc': + 'https://developers.google.com/ml-kit/vision/text-recognition', }, ), ], diff --git a/lib/my_app_settings.dart b/lib/my_app_settings.dart index 96b1d21d..c9e94db0 100644 --- a/lib/my_app_settings.dart +++ b/lib/my_app_settings.dart @@ -24,17 +24,17 @@ class MyAppSettings extends ChangeNotifier { } } - bool get isDarkMode => _pref?.getBool(_kDarkModePreferenceKey) ?? false; + bool get isDarkMode => _pref.getBool(_kDarkModePreferenceKey) ?? false; // ignore:avoid_positional_boolean_parameters void setDarkMode(bool val) { - _pref?.setBool(_kDarkModePreferenceKey, val); + _pref.setBool(_kDarkModePreferenceKey, val); notifyListeners(); } /// The list of route names in search history. List get searchHistory => - _pref?.getStringList(_kSearchHistoryPreferenceKey) ?? []; + _pref.getStringList(_kSearchHistoryPreferenceKey) ?? []; void addSearchHistory(String routeName) { List history = this.searchHistory; @@ -43,16 +43,16 @@ class MyAppSettings extends ChangeNotifier { if (history.length >= 10) { history = history.take(10).toList(); } - _pref?.setStringList(_kSearchHistoryPreferenceKey, history); + _pref.setStringList(_kSearchHistoryPreferenceKey, history); } List get starredRoutenames => - _pref?.getStringList(_kBookmarkedRoutesPreferenceKey) ?? []; + _pref.getStringList(_kBookmarkedRoutesPreferenceKey) ?? []; List get starredRoutes => [ for (String routename in this.starredRoutenames) if (_kRoutenameToRouteMap[routename] != null) - _kRoutenameToRouteMap[routename] + _kRoutenameToRouteMap[routename]! ]; // Returns a widget showing the star status of one demo route. @@ -67,8 +67,7 @@ class MyAppSettings extends ChangeNotifier { ); } - bool isStarred(String routeName) => - starredRoutenames.contains(routeName) ?? false; + bool isStarred(String routeName) => starredRoutenames.contains(routeName); void toggleStarred(String routeName) { final staredRoutes = this.starredRoutenames; @@ -78,7 +77,7 @@ class MyAppSettings extends ChangeNotifier { staredRoutes.add(routeName); } final dedupedStaredRoutes = Set.from(staredRoutes).toList(); - _pref?.setStringList(_kBookmarkedRoutesPreferenceKey, dedupedStaredRoutes); + _pref.setStringList(_kBookmarkedRoutesPreferenceKey, dedupedStaredRoutes); notifyListeners(); } @@ -86,12 +85,12 @@ class MyAppSettings extends ChangeNotifier { // for newly added routes. static const _kKnownRoutesKey = 'KNOWN_ROUTES'; bool isNewRoute(String routeName) => - !_pref.getStringList(_kKnownRoutesKey).contains(routeName); + !(_pref.getStringList(_kKnownRoutesKey)?.contains(routeName) ?? false); void markRouteKnown(String routeName) { if (isNewRoute(routeName)) { - final knowRoutes = _pref.getStringList(_kKnownRoutesKey)..add(routeName); - _pref.setStringList(_kKnownRoutesKey, knowRoutes); + final knowRoutes = _pref.getStringList(_kKnownRoutesKey)?..add(routeName); + _pref.setStringList(_kKnownRoutesKey, knowRoutes ?? []); notifyListeners(); } } diff --git a/lib/my_main_app.dart b/lib/my_main_app.dart index f53e821d..4b669195 100644 --- a/lib/my_main_app.dart +++ b/lib/my_main_app.dart @@ -8,7 +8,7 @@ import './themes.dart'; class MyMainApp extends StatelessWidget { final SharedPreferences sharedPref; - const MyMainApp(this.sharedPref, {Key key}) : super(key: key); + const MyMainApp(this.sharedPref, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -20,7 +20,7 @@ class MyMainApp extends StatelessWidget { } class _MyMaterialApp extends StatelessWidget { - const _MyMaterialApp({Key key}) : super(key: key); + const _MyMaterialApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/my_route.dart b/lib/my_route.dart index 100dab72..dcc5d1d4 100644 --- a/lib/my_route.dart +++ b/lib/my_route.dart @@ -19,25 +19,25 @@ class MyRoute extends StatelessWidget { // Actual content of the example. final Widget child; // Title shown in the route's appbar. By default just returns routeName. - final String _title; + final String? _title; // A short description of the route. If not null, will be shown as subtitle in // the home page list tile. final String description; // Returns a set of links {title:link} that are relative to the route. Can put // documention links or reference video/article links here. final Map links; - // Route name of a page. - final String _routeName; + // Route name of a page, if missing, use ${child.runtimeType}. + final String? _routeName; final Iterable supportedPlatforms; const MyRoute({ - Key key, - @required this.sourceFilePath, - @required this.child, - String title, - this.description, - this.links, - String routeName, + Key? key, + required this.sourceFilePath, + required this.child, + String? title, + this.description = '', + this.links = const {}, + String? routeName, this.supportedPlatforms = PlatformType.values, }) : _title = title, _routeName = routeName, @@ -99,7 +99,7 @@ class MyRoute extends StatelessWidget { ), if (this.routeName != Navigator.defaultRouteName) settings.starStatusOfRoute(this.routeName), - if (this.links?.isNotEmpty ?? false) + if (this.links.isNotEmpty) PopupMenuButton( itemBuilder: (context) { return [ diff --git a/lib/my_route_search_delegate.dart b/lib/my_route_search_delegate.dart index c86dbcb0..02c05afa 100644 --- a/lib/my_route_search_delegate.dart +++ b/lib/my_route_search_delegate.dart @@ -29,7 +29,7 @@ class MyRouteSearchDelegate extends SearchDelegate { return IconButton( tooltip: 'Back', icon: const Icon(Icons.arrow_back), - onPressed: () => this.close(context, null), + onPressed: () => this.close(context, ''), ); } @@ -44,15 +44,13 @@ class MyRouteSearchDelegate extends SearchDelegate { // List suggestions = _history; Iterable suggestions = [ for (final routeName in Provider.of(context).searchHistory) - kRouteNameToRoute[routeName] + kRouteNameToRoute[routeName]! ]; if (this.query.isNotEmpty) { suggestions = kAllRoutes .where((route) => route.title.toLowerCase().contains(query.toLowerCase()) || - (route.description ?? '') - .toLowerCase() - .contains(query.toLowerCase())) + route.description.toLowerCase().contains(query.toLowerCase())) .toList(); } return _buildSuggestionsList(suggestions); @@ -63,7 +61,7 @@ class MyRouteSearchDelegate extends SearchDelegate { itemCount: suggestions.length, itemBuilder: (BuildContext context, int i) { final route = suggestions.elementAt(i); - final routeGroup = kRouteNameToRouteGroup[route.routeName]; + final routeGroup = kRouteNameToRouteGroup[route.routeName]!; return ListTile( leading: query.isEmpty ? const Icon(Icons.history) : routeGroup.icon, title: SubstringHighlight( @@ -71,15 +69,15 @@ class MyRouteSearchDelegate extends SearchDelegate { term: query, textStyle: Theme.of(context) .textTheme - .bodyText2 + .bodyText2! .copyWith(fontWeight: FontWeight.bold), ), - subtitle: route.description == null + subtitle: route.description.isEmpty ? null : SubstringHighlight( text: route.description, term: query, - textStyle: Theme.of(context).textTheme.bodyText2, + textStyle: Theme.of(context).textTheme.bodyText2!, ), onTap: () { Provider.of(context, listen: false) diff --git a/lib/routes/about.dart b/lib/routes/about.dart index e983f60c..f05f4926 100644 --- a/lib/routes/about.dart +++ b/lib/routes/about.dart @@ -6,7 +6,7 @@ import 'package:flutter_catalog/constants.dart'; // Inspired by the about page in Eajy's flutter demo: // https://github.com/Eajy/flutter_demo/blob/master/lib/route/about.dart class MyAboutRoute extends StatelessWidget { - const MyAboutRoute({Key key}) : super(key: key); + const MyAboutRoute({Key? key}) : super(key: key); // These tiles are also used as drawer nav items in home route. static final List kAboutListTiles = [ diff --git a/lib/routes/animation_animated_builder_ex.dart b/lib/routes/animation_animated_builder_ex.dart index ae4a6bf2..48ad1827 100644 --- a/lib/routes/animation_animated_builder_ex.dart +++ b/lib/routes/animation_animated_builder_ex.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; class AnimatedBuilderExample extends StatefulWidget { - const AnimatedBuilderExample({Key key}) : super(key: key); + const AnimatedBuilderExample({Key? key}) : super(key: key); @override _AnimatedBuilderExampleState createState() => _AnimatedBuilderExampleState(); @@ -10,7 +10,7 @@ class AnimatedBuilderExample extends StatefulWidget { class _AnimatedBuilderExampleState extends State with SingleTickerProviderStateMixin { - AnimationController _controller; + late AnimationController _controller; @override void initState() { diff --git a/lib/routes/animation_animated_container_ex.dart b/lib/routes/animation_animated_container_ex.dart index 18716a72..7ed75951 100644 --- a/lib/routes/animation_animated_container_ex.dart +++ b/lib/routes/animation_animated_container_ex.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; class AnimatedContainerExample extends StatefulWidget { - const AnimatedContainerExample({Key key}) : super(key: key); + const AnimatedContainerExample({Key? key}) : super(key: key); @override _AnimatedContainerExampleState createState() => diff --git a/lib/routes/animation_animated_icons_ex.dart b/lib/routes/animation_animated_icons_ex.dart index b73e6ae0..05539126 100644 --- a/lib/routes/animation_animated_icons_ex.dart +++ b/lib/routes/animation_animated_icons_ex.dart @@ -18,7 +18,7 @@ const _kAllANimatedIcons = { }; class AnimatedIconsExample extends StatelessWidget { - const AnimatedIconsExample({Key key}) : super(key: key); + const AnimatedIconsExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -47,8 +47,7 @@ class _AnimIconDemoBox extends StatefulWidget { final AnimatedIconData iconData; final String name; - const _AnimIconDemoBox( - {Key key, @required this.iconData, @required this.name}) + const _AnimIconDemoBox({Key? key, required this.iconData, required this.name}) : super(key: key); @override @@ -58,7 +57,7 @@ class _AnimIconDemoBox extends StatefulWidget { // ! Add SingleTickerProviderStateMixin to use animation controllers. class _AnimIconDemoBoxState extends State<_AnimIconDemoBox> with SingleTickerProviderStateMixin { - AnimationController _animationController; + late AnimationController _animationController; @override void initState() { diff --git a/lib/routes/animation_animated_radial_menu_ex.dart b/lib/routes/animation_animated_radial_menu_ex.dart index c82b3105..d2b53e15 100644 --- a/lib/routes/animation_animated_radial_menu_ex.dart +++ b/lib/routes/animation_animated_radial_menu_ex.dart @@ -2,7 +2,7 @@ import 'package:animated_radial_menu/animated_radial_menu.dart'; import 'package:flutter/material.dart'; class RadialMenuExample extends StatelessWidget { - const RadialMenuExample({Key key}) : super(key: key); + const RadialMenuExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -45,7 +45,7 @@ class RadialMenuExample extends StatelessWidget { } class TargetScreen extends StatelessWidget { - const TargetScreen({Key key}) : super(key: key); + const TargetScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/animation_animated_text_kit_ex.dart b/lib/routes/animation_animated_text_kit_ex.dart index e6f8f3fe..fc77d1bb 100644 --- a/lib/routes/animation_animated_text_kit_ex.dart +++ b/lib/routes/animation_animated_text_kit_ex.dart @@ -9,7 +9,7 @@ const _kTextStyle = TextStyle( ); class AnimatedTextKitExample extends StatelessWidget { - const AnimatedTextKitExample({Key key}) : super(key: key); + const AnimatedTextKitExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -21,7 +21,7 @@ class AnimatedTextKitExample extends StatelessWidget { TextLiquidFill( text: 'LIQUIDY', waveColor: Colors.blueAccent, - boxBackgroundColor: Colors.red[100], + boxBackgroundColor: Colors.red[100]!, textStyle: const TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold), boxHeight: 300.0, diff --git a/lib/routes/animation_animated_widget_ex.dart b/lib/routes/animation_animated_widget_ex.dart index 05b266c9..e96000cc 100644 --- a/lib/routes/animation_animated_widget_ex.dart +++ b/lib/routes/animation_animated_widget_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // The AnimatedWidget base class allows you to separate out the core widget code // from the animation code. class _AnimatedLogo extends AnimatedWidget { - const _AnimatedLogo({Key key, Animation animation}) + const _AnimatedLogo({Key? key, required Animation animation}) : super(key: key, listenable: animation); @override @@ -21,15 +21,15 @@ class _AnimatedLogo extends AnimatedWidget { } class AnimatedWidgetExample extends StatefulWidget { - const AnimatedWidgetExample({Key key}) : super(key: key); + const AnimatedWidgetExample({Key? key}) : super(key: key); @override _AnimatedWidgetExampleState createState() => _AnimatedWidgetExampleState(); } class _AnimatedWidgetExampleState extends State with SingleTickerProviderStateMixin { - Animation _sizeAnimation; - AnimationController _controller; + late Animation _sizeAnimation; + late AnimationController _controller; @override void initState() { diff --git a/lib/routes/animation_animations_pkg_ex.dart b/lib/routes/animation_animations_pkg_ex.dart index f1473e5a..3ce9e1b2 100644 --- a/lib/routes/animation_animations_pkg_ex.dart +++ b/lib/routes/animation_animations_pkg_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; class AnimationsPackageExample extends StatelessWidget { - const AnimationsPackageExample({Key key}) : super(key: key); + const AnimationsPackageExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -95,7 +95,7 @@ class AnimationsPackageExample extends StatelessWidget { } class _PageTransitionSwitcherEx extends StatefulWidget { - const _PageTransitionSwitcherEx({Key key}) : super(key: key); + const _PageTransitionSwitcherEx({Key? key}) : super(key: key); @override __PageTransitionSwitcherExState createState() => @@ -147,7 +147,7 @@ class __PageTransitionSwitcherExState extends State<_PageTransitionSwitcherEx> { } class _SharedAxisEx extends StatefulWidget { - const _SharedAxisEx({Key key}) : super(key: key); + const _SharedAxisEx({Key? key}) : super(key: key); @override __SharedAxisExState createState() => __SharedAxisExState(); @@ -232,8 +232,9 @@ class __SharedAxisExState extends State<_SharedAxisEx> { .substring('SharedAxisTransitionType.'.length)), ) ], - onChanged: (SharedAxisTransitionType val) => - setState(() => this._transitionType = val), + onChanged: (SharedAxisTransitionType? val) { + if (val != null) setState(() => this._transitionType = val); + }, ), ), ], diff --git a/lib/routes/animation_hero_ex.dart b/lib/routes/animation_hero_ex.dart index 8d6ff9c6..43610ec4 100644 --- a/lib/routes/animation_hero_ex.dart +++ b/lib/routes/animation_hero_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class HeroExample extends StatelessWidget { - const HeroExample({Key key}) : super(key: key); + const HeroExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/animation_lottie_ex.dart b/lib/routes/animation_lottie_ex.dart index 8731f10b..64464a3d 100644 --- a/lib/routes/animation_lottie_ex.dart +++ b/lib/routes/animation_lottie_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; class LottieExample extends StatelessWidget { - const LottieExample({Key key}) : super(key: key); + const LottieExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -31,7 +31,7 @@ class _LottieCustom extends StatefulWidget { class __LottieCustomState extends State<_LottieCustom> with TickerProviderStateMixin { - AnimationController _controller; + late AnimationController _controller; @override void initState() { diff --git a/lib/routes/animation_low_level_ex.dart b/lib/routes/animation_low_level_ex.dart index c4cfb9f3..84e862ae 100644 --- a/lib/routes/animation_low_level_ex.dart +++ b/lib/routes/animation_low_level_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class LowLevelAnimationExample extends StatefulWidget { - const LowLevelAnimationExample({Key key}) : super(key: key); + const LowLevelAnimationExample({Key? key}) : super(key: key); @override _LowLevelAnimationExampleState createState() => @@ -15,14 +15,14 @@ class _LowLevelAnimationExampleState extends State // An Animation object knows the current state of an animation (for example, // whether it’s started, stopped, or moving forward or in reverse), but // doesn’t know anything about what appears onscreen. - Animation _sizeAnimation; - Animation _colorAnimation; + late Animation _sizeAnimation; + late Animation _colorAnimation; // Both AnimationController and CurvedAnimation extends Animation, // but add additional methods // An AnimationController manages the Animation. - AnimationController _controller; + late AnimationController _controller; // A CurvedAnimation defines progression as a non-linear curve. - CurvedAnimation _curve; + late CurvedAnimation _curve; @override void initState() { diff --git a/lib/routes/animation_opacity_ex.dart b/lib/routes/animation_opacity_ex.dart index 884af22d..d4f1b633 100644 --- a/lib/routes/animation_opacity_ex.dart +++ b/lib/routes/animation_opacity_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class OpacityExample extends StatefulWidget { - const OpacityExample({Key key}) : super(key: key); + const OpacityExample({Key? key}) : super(key: key); @override State createState() => _OpacityExampleState(); diff --git a/lib/routes/appbar_backdrop_ex.dart b/lib/routes/appbar_backdrop_ex.dart index 58fd4b52..62dc573c 100644 --- a/lib/routes/appbar_backdrop_ex.dart +++ b/lib/routes/appbar_backdrop_ex.dart @@ -2,7 +2,7 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; class BackdropExample extends StatelessWidget { - const BackdropExample({Key key}) : super(key: key); + const BackdropExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/appbar_basic_appbar_ex.dart b/lib/routes/appbar_basic_appbar_ex.dart index 412dcd61..3c09cc33 100644 --- a/lib/routes/appbar_basic_appbar_ex.dart +++ b/lib/routes/appbar_basic_appbar_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class BasicAppbarExample extends StatelessWidget { - const BasicAppbarExample({Key key}) : super(key: key); + const BasicAppbarExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/appbar_bottom_appbar_ex.dart b/lib/routes/appbar_bottom_appbar_ex.dart index d980c815..0e087f2d 100644 --- a/lib/routes/appbar_bottom_appbar_ex.dart +++ b/lib/routes/appbar_bottom_appbar_ex.dart @@ -4,7 +4,7 @@ import 'package:fluttertoast/fluttertoast.dart'; // Adapted from offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/bottom_app_bar_demo.dart class BottomAppbarExample extends StatefulWidget { - const BottomAppbarExample({Key key}) : super(key: key); + const BottomAppbarExample({Key? key}) : super(key: key); @override _BottomAppbarExampleState createState() => _BottomAppbarExampleState(); @@ -26,7 +26,7 @@ class _BottomAppbarExampleState extends State { title: const Text('FloatingActionButton position:'), trailing: DropdownButton( value: this._fabLocation, - onChanged: (FloatingActionButtonLocation newVal) { + onChanged: (FloatingActionButtonLocation? newVal) { if (newVal != null) { setState(() => this._fabLocation = newVal); } diff --git a/lib/routes/appbar_convex_appbar_ex.dart b/lib/routes/appbar_convex_appbar_ex.dart index a5679f16..d656aaa5 100644 --- a/lib/routes/appbar_convex_appbar_ex.dart +++ b/lib/routes/appbar_convex_appbar_ex.dart @@ -10,7 +10,7 @@ const _kPages = { }; class ConvexAppExample extends StatefulWidget { - const ConvexAppExample({Key key}) : super(key: key); + const ConvexAppExample({Key? key}) : super(key: key); @override _ConvexAppExampleState createState() => _ConvexAppExampleState(); @@ -58,7 +58,7 @@ class _ConvexAppExampleState extends State { final dropdown = DropdownButton( value: _tabStyle, onChanged: (newStyle) { - setState(() => _tabStyle = newStyle); + if (newStyle != null) setState(() => _tabStyle = newStyle); }, items: [ for (final style in TabStyle.values) diff --git a/lib/routes/appbar_search_ex.dart b/lib/routes/appbar_search_ex.dart index 5dbab04a..038c287a 100644 --- a/lib/routes/appbar_search_ex.dart +++ b/lib/routes/appbar_search_ex.dart @@ -4,7 +4,7 @@ import 'package:english_words/english_words.dart' as english_words; // Adapted from search demo in offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/search_demo.dart class AppBarSearchExample extends StatefulWidget { - const AppBarSearchExample({Key key}) : super(key: key); + const AppBarSearchExample({Key? key}) : super(key: key); @override _AppBarSearchExampleState createState() => _AppBarSearchExampleState(); @@ -12,7 +12,7 @@ class AppBarSearchExample extends StatefulWidget { class _AppBarSearchExampleState extends State { final List kEnglishWords; - _MySearchDelegate _delegate; + late _MySearchDelegate _delegate; _AppBarSearchExampleState() : kEnglishWords = List.from(Set.from(english_words.all)) @@ -38,7 +38,7 @@ class _AppBarSearchExampleState extends State { tooltip: 'Search', icon: const Icon(Icons.search), onPressed: () async { - final String selected = await showSearch( + final String? selected = await showSearch( context: context, delegate: _delegate, ); @@ -87,7 +87,7 @@ class _MySearchDelegate extends SearchDelegate { ), onPressed: () { // SearchDelegate.close() can return vlaues, similar to Navigator.pop(). - this.close(context, null); + this.close(context, ''); }, ); } @@ -112,7 +112,7 @@ class _MySearchDelegate extends SearchDelegate { this.query, style: Theme.of(context) .textTheme - .headline4 + .headline4! .copyWith(fontWeight: FontWeight.bold), ), ), @@ -167,7 +167,10 @@ class _MySearchDelegate extends SearchDelegate { // Suggestions list widget displayed in the search page. class _SuggestionList extends StatelessWidget { - const _SuggestionList({this.suggestions, this.query, this.onSelected}); + const _SuggestionList( + {required this.suggestions, + required this.query, + required this.onSelected}); final List suggestions; final String query; @@ -175,7 +178,7 @@ class _SuggestionList extends StatelessWidget { @override Widget build(BuildContext context) { - final textTheme = Theme.of(context).textTheme.subtitle1; + final textTheme = Theme.of(context).textTheme.subtitle1!; return ListView.builder( itemCount: suggestions.length, itemBuilder: (BuildContext context, int i) { diff --git a/lib/routes/appbar_sliver_appbar_ex.dart b/lib/routes/appbar_sliver_appbar_ex.dart index eb0ebee4..9d714160 100644 --- a/lib/routes/appbar_sliver_appbar_ex.dart +++ b/lib/routes/appbar_sliver_appbar_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Adapted from offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/bottom_app_bar_demo.dart class SliverAppBarExample extends StatefulWidget { - const SliverAppBarExample({Key key}) : super(key: key); + const SliverAppBarExample({Key? key}) : super(key: key); @override State createState() => _SliverAppBarExampleState(); diff --git a/lib/routes/async_futurebuilder_ex.dart b/lib/routes/async_futurebuilder_ex.dart index 63102c1d..2cf5af16 100644 --- a/lib/routes/async_futurebuilder_ex.dart +++ b/lib/routes/async_futurebuilder_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class FutureBuilderExample extends StatefulWidget { - const FutureBuilderExample({Key key}) : super(key: key); + const FutureBuilderExample({Key? key}) : super(key: key); @override FutureBuilderExampleState createState() => FutureBuilderExampleState(); @@ -37,7 +37,7 @@ class FutureBuilderExampleState extends State { // This shouldn't happen in our case, but good to handle errors. return const Text('Error has happened in the future!'); } else { - return Image.memory(snapshot.data.buffer.asUint8List()); + return Image.memory(snapshot.data!.buffer.asUint8List()); } }, ), diff --git a/lib/routes/async_streambuilder_ex.dart b/lib/routes/async_streambuilder_ex.dart index a720fbf5..79c9547f 100644 --- a/lib/routes/async_streambuilder_ex.dart +++ b/lib/routes/async_streambuilder_ex.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; class StreamBuilderExample extends StatefulWidget { - const StreamBuilderExample({Key key}) : super(key: key); + const StreamBuilderExample({Key? key}) : super(key: key); @override StreamBuilderExampleState createState() => StreamBuilderExampleState(); @@ -33,7 +33,7 @@ class StreamBuilderExampleState extends State { if (snapshot.hasData) { if (snapshot.data != this._previousStreamValue) { print('Latest snapshot from stream: ${snapshot.data}'); - this._previousStreamValue = snapshot.data; + this._previousStreamValue = snapshot.data!; if (!_paused) { this._timerValue++; } diff --git a/lib/routes/async_streamcontroller_ex.dart b/lib/routes/async_streamcontroller_ex.dart index 6c26a927..273f7bd8 100644 --- a/lib/routes/async_streamcontroller_ex.dart +++ b/lib/routes/async_streamcontroller_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart' as english_words; class StreamControllerExample extends StatefulWidget { - const StreamControllerExample({Key key}) : super(key: key); + const StreamControllerExample({Key? key}) : super(key: key); @override _StreamControllerExampleState createState() => @@ -16,7 +16,7 @@ class _Data { final String message; final DateTime timestamp; - _Data({@required this.message, @required this.timestamp}); + _Data({required this.message, required this.timestamp}); } class _StreamControllerExampleState extends State { @@ -67,7 +67,7 @@ class _StreamControllerExampleState extends State { title: Text('no data'), ); } - final Widget widgetToRender = snapshot.data; + final Widget widgetToRender = snapshot.data!; return widgetToRender; }, ), diff --git a/lib/routes/charts_fl_bar_chart_ex.dart b/lib/routes/charts_fl_bar_chart_ex.dart index 07a82337..64c1613d 100644 --- a/lib/routes/charts_fl_bar_chart_ex.dart +++ b/lib/routes/charts_fl_bar_chart_ex.dart @@ -7,7 +7,7 @@ final _data1 = {1: 9, 2: 12, 3: 10, 4: 20, 5: 14, 6: 18}; final _data2 = {1: 8, 2: 15, 3: 17, 4: 11, 5: 13, 6: 20}; class FlBarChartExample extends StatefulWidget { - const FlBarChartExample({Key key}) : super(key: key); + const FlBarChartExample({Key? key}) : super(key: key); @override _FlBarChartExampleState createState() => _FlBarChartExampleState(); @@ -26,7 +26,7 @@ class _FlBarChartExampleState extends State { x: entry.key.toInt(), barRods: [ BarChartRodData(y: entry.value, colors: [Colors.blue]), - BarChartRodData(y: _data2[entry.key], colors: [Colors.red]), + BarChartRodData(y: _data2[entry.key]!, colors: [Colors.red]), ], ), ]; diff --git a/lib/routes/charts_fl_line_chart_ex.dart b/lib/routes/charts_fl_line_chart_ex.dart index 885e4faf..9210716f 100644 --- a/lib/routes/charts_fl_line_chart_ex.dart +++ b/lib/routes/charts_fl_line_chart_ex.dart @@ -7,7 +7,7 @@ final _data1 = {1: 10, 2: 15, 3: 20, 4: 28, 5: 34, 6: 50}; final _data2 = {1: 8, 2: 12, 3: 27, 4: 31, 5: 36, 6: 45}; class FlLineChartExample extends StatefulWidget { - const FlLineChartExample({Key key}) : super(key: key); + const FlLineChartExample({Key? key}) : super(key: key); @override _FlLineChartExampleState createState() => _FlLineChartExampleState(); @@ -43,7 +43,7 @@ class _FlLineChartExampleState extends State { isCurved: _isCurved, dotData: FlDotData(show: _showDot), belowBarData: - BarAreaData(show: _showBelowArea, colors: [Colors.blue[200]]), + BarAreaData(show: _showBelowArea, colors: [Colors.blue[200]!]), ), LineChartBarData( spots: spots2, @@ -52,7 +52,7 @@ class _FlLineChartExampleState extends State { isCurved: _isCurved, dotData: FlDotData(show: _showDot), belowBarData: - BarAreaData(show: _showBelowArea, colors: [Colors.red[200]]), + BarAreaData(show: _showBelowArea, colors: [Colors.red[200]!]), ), ], // ! Behavior when touching the chart: diff --git a/lib/routes/charts_fl_pie_chart_ex.dart b/lib/routes/charts_fl_pie_chart_ex.dart index e7385ebf..c6857059 100644 --- a/lib/routes/charts_fl_pie_chart_ex.dart +++ b/lib/routes/charts_fl_pie_chart_ex.dart @@ -11,7 +11,7 @@ final _data = >[ ]; class FlPieChartExample extends StatefulWidget { - const FlPieChartExample({Key key}) : super(key: key); + const FlPieChartExample({Key? key}) : super(key: key); @override _FlPieChartExampleState createState() => _FlPieChartExampleState(); @@ -46,7 +46,9 @@ class _FlPieChartExampleState extends State { pieTouchData: PieTouchData( enabled: true, touchCallback: (pieTouchResponse) => setState(() { - _touchedIdx = pieTouchResponse.touchedSection.touchedSectionIndex; + if (pieTouchResponse.touchedSection != null) { + _touchedIdx = pieTouchResponse.touchedSection!.touchedSectionIndex; + } }), ), centerSpaceRadius: _innerRadius, diff --git a/lib/routes/charts_graphview_ex.dart b/lib/routes/charts_graphview_ex.dart index 194596a9..9a730aef 100644 --- a/lib/routes/charts_graphview_ex.dart +++ b/lib/routes/charts_graphview_ex.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:graphview/GraphView.dart'; class GraphViewExample extends StatelessWidget { - const GraphViewExample({Key key}) : super(key: key); + const GraphViewExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -22,7 +22,7 @@ class GraphViewExample extends StatelessWidget { } class GraphViewEx extends StatefulWidget { - const GraphViewEx({Key key}) : super(key: key); + const GraphViewEx({Key? key}) : super(key: key); @override _GraphViewExState createState() => _GraphViewExState(); @@ -62,8 +62,8 @@ class _GraphViewExState extends State { ); final algo = FruchtermanReingoldAlgorithm(iterations: this._iterations) - ..rand = Random(/*seed=*/ 0) // For deterministic rendering - ..attractionK = 100; + ..rand = Random(/*seed=*/ 0) // For deterministic rendering + ; return Scaffold( body: InteractiveViewer( diff --git a/lib/routes/charts_heatmap_calendar_ex.dart b/lib/routes/charts_heatmap_calendar_ex.dart index 6392c0d4..ad686e1d 100644 --- a/lib/routes/charts_heatmap_calendar_ex.dart +++ b/lib/routes/charts_heatmap_calendar_ex.dart @@ -3,7 +3,7 @@ import 'package:heatmap_calendar/heatmap_calendar.dart'; import 'package:heatmap_calendar/time_utils.dart'; class HeatmapCalendarExample extends StatelessWidget { - const HeatmapCalendarExample({Key key}) : super(key: key); + const HeatmapCalendarExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -36,7 +36,7 @@ class HeatmapCalendarExample extends StatelessWidget { squareSize: 18, textOpacity: 0.3, labelTextColor: Colors.blueGrey, - dayTextColor: Colors.blue[500], + dayTextColor: Colors.blue[500]!, // Week day and month labels can be overriden: // weekDaysLabels: const ['S', 'M', 'T', 'W', 'T', 'F', 'S'], // monthsLabels: const ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', diff --git a/lib/routes/charts_pie_chart_ex.dart b/lib/routes/charts_pie_chart_ex.dart index 224d1ffe..88daa77f 100644 --- a/lib/routes/charts_pie_chart_ex.dart +++ b/lib/routes/charts_pie_chart_ex.dart @@ -10,7 +10,7 @@ class _CostsData { } class PieChartExample extends StatefulWidget { - const PieChartExample({Key key}) : super(key: key); + const PieChartExample({Key? key}) : super(key: key); @override _PieChartExampleState createState() => _PieChartExampleState(); @@ -47,7 +47,7 @@ class _PieChartExampleState extends State { /*seriesList=*/ [ charts.Series<_CostsData, String>( id: 'Sales-1', - colorFn: (_, idx) => _colorPalettes[idx].shadeDefault, + colorFn: (_, idx) => _colorPalettes[idx!].shadeDefault, domainFn: (_CostsData sales, _) => sales.category, measureFn: (_CostsData sales, _) => sales.cost, data: this._data, @@ -107,7 +107,7 @@ class _PieChartExampleState extends State { title: const Text('arcLabelPosition:'), trailing: DropdownButton( value: this._arcLabelPosition, - onChanged: (charts.ArcLabelPosition newVal) { + onChanged: (charts.ArcLabelPosition? newVal) { if (newVal != null) { setState(() => this._arcLabelPosition = newVal); } @@ -122,7 +122,7 @@ class _PieChartExampleState extends State { title: const Text('titlePosition:'), trailing: DropdownButton( value: this._titlePosition, - onChanged: (charts.BehaviorPosition newVal) { + onChanged: (charts.BehaviorPosition? newVal) { if (newVal != null) { setState(() => this._titlePosition = newVal); } @@ -137,7 +137,7 @@ class _PieChartExampleState extends State { title: const Text('legendPosition:'), trailing: DropdownButton( value: this._legendPosition, - onChanged: (charts.BehaviorPosition newVal) { + onChanged: (charts.BehaviorPosition? newVal) { if (newVal != null) { setState(() => this._legendPosition = newVal); } diff --git a/lib/routes/charts_radar_chart_ex.dart b/lib/routes/charts_radar_chart_ex.dart index f74bc200..6703c08a 100644 --- a/lib/routes/charts_radar_chart_ex.dart +++ b/lib/routes/charts_radar_chart_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_radar_chart/flutter_radar_chart.dart'; class RadarChartExample extends StatelessWidget { - const RadarChartExample({Key key}) : super(key: key); + const RadarChartExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/charts_time_series_ex.dart b/lib/routes/charts_time_series_ex.dart index c4c0c47a..d65f0175 100644 --- a/lib/routes/charts_time_series_ex.dart +++ b/lib/routes/charts_time_series_ex.dart @@ -24,7 +24,7 @@ List<_SalesData> _genRandData() { } class TimeseriesChartExample extends StatefulWidget { - const TimeseriesChartExample({Key key}) : super(key: key); + const TimeseriesChartExample({Key? key}) : super(key: key); @override _TimeseriesChartExampleState createState() => _TimeseriesChartExampleState(); @@ -41,7 +41,7 @@ class _TimeseriesChartExampleState extends State { charts.BehaviorPosition _legendPosition = charts.BehaviorPosition.bottom; // Data to render. - List<_SalesData> _series1, _series2; + late List<_SalesData> _series1, _series2; @override void initState() { @@ -135,7 +135,7 @@ class _TimeseriesChartExampleState extends State { title: const Text('titlePosition:'), trailing: DropdownButton( value: this._titlePosition, - onChanged: (charts.BehaviorPosition newVal) { + onChanged: (charts.BehaviorPosition? newVal) { if (newVal != null) { setState(() => this._titlePosition = newVal); } @@ -150,7 +150,7 @@ class _TimeseriesChartExampleState extends State { title: const Text('legendPosition:'), trailing: DropdownButton( value: this._legendPosition, - onChanged: (charts.BehaviorPosition newVal) { + onChanged: (charts.BehaviorPosition? newVal) { if (newVal != null) { setState(() => this._legendPosition = newVal); } diff --git a/lib/routes/data/my_api_state.freezed.dart b/lib/routes/data/my_api_state.freezed.dart index 4cc02d9e..892b94a4 100644 --- a/lib/routes/data/my_api_state.freezed.dart +++ b/lib/routes/data/my_api_state.freezed.dart @@ -1,5 +1,5 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides part of 'my_api_state.dart'; @@ -9,62 +9,65 @@ part of 'my_api_state.dart'; T _$identity(T value) => value; +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + /// @nodoc class _$MyApiStateTearOff { const _$MyApiStateTearOff(); -// ignore: unused_element SuccessState success(List data) { return SuccessState( data, ); } -// ignore: unused_element ErrorState error(String errorMsg) { return ErrorState( errorMsg, ); } -// ignore: unused_element LoadingState loading() { return LoadingState(); } } /// @nodoc -// ignore: unused_element const $MyApiState = _$MyApiStateTearOff(); /// @nodoc mixin _$MyApiState { @optionalTypeArgs - TResult when({ - @required TResult success(List data), - @required TResult error(String errorMsg), - @required TResult loading(), - }); + TResult when({ + required TResult Function(List data) success, + required TResult Function(String errorMsg) error, + required TResult Function() loading, + }) => + throw _privateConstructorUsedError; @optionalTypeArgs - TResult maybeWhen({ - TResult success(List data), - TResult error(String errorMsg), - TResult loading(), - @required TResult orElse(), - }); + TResult maybeWhen({ + TResult Function(List data)? success, + TResult Function(String errorMsg)? error, + TResult Function()? loading, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; @optionalTypeArgs - TResult map({ - @required TResult success(SuccessState value), - @required TResult error(ErrorState value), - @required TResult loading(LoadingState value), - }); + TResult map({ + required TResult Function(SuccessState value) success, + required TResult Function(ErrorState value) error, + required TResult Function(LoadingState value) loading, + }) => + throw _privateConstructorUsedError; @optionalTypeArgs - TResult maybeMap({ - TResult success(SuccessState value), - TResult error(ErrorState value), - TResult loading(LoadingState value), - @required TResult orElse(), - }); + TResult maybeMap({ + TResult Function(SuccessState value)? success, + TResult Function(ErrorState value)? error, + TResult Function(LoadingState value)? loading, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; } /// @nodoc @@ -103,17 +106,21 @@ class _$SuccessStateCopyWithImpl<$Res> extends _$MyApiStateCopyWithImpl<$Res> @override $Res call({ - Object data = freezed, + Object? data = freezed, }) { return _then(SuccessState( - data == freezed ? _value.data : data as List, + data == freezed + ? _value.data + : data // ignore: cast_nullable_to_non_nullable + as List, )); } } /// @nodoc + class _$SuccessState implements SuccessState { - _$SuccessState(this.data) : assert(data != null); + _$SuccessState(this.data); @override final List data; @@ -142,26 +149,22 @@ class _$SuccessState implements SuccessState { @override @optionalTypeArgs - TResult when({ - @required TResult success(List data), - @required TResult error(String errorMsg), - @required TResult loading(), + TResult when({ + required TResult Function(List data) success, + required TResult Function(String errorMsg) error, + required TResult Function() loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return success(data); } @override @optionalTypeArgs - TResult maybeWhen({ - TResult success(List data), - TResult error(String errorMsg), - TResult loading(), - @required TResult orElse(), + TResult maybeWhen({ + TResult Function(List data)? success, + TResult Function(String errorMsg)? error, + TResult Function()? loading, + required TResult orElse(), }) { - assert(orElse != null); if (success != null) { return success(data); } @@ -170,26 +173,22 @@ class _$SuccessState implements SuccessState { @override @optionalTypeArgs - TResult map({ - @required TResult success(SuccessState value), - @required TResult error(ErrorState value), - @required TResult loading(LoadingState value), + TResult map({ + required TResult Function(SuccessState value) success, + required TResult Function(ErrorState value) error, + required TResult Function(LoadingState value) loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return success(this); } @override @optionalTypeArgs - TResult maybeMap({ - TResult success(SuccessState value), - TResult error(ErrorState value), - TResult loading(LoadingState value), - @required TResult orElse(), + TResult maybeMap({ + TResult Function(SuccessState value)? success, + TResult Function(ErrorState value)? error, + TResult Function(LoadingState value)? loading, + required TResult orElse(), }) { - assert(orElse != null); if (success != null) { return success(this); } @@ -200,9 +199,10 @@ class _$SuccessState implements SuccessState { abstract class SuccessState implements MyApiState { factory SuccessState(List data) = _$SuccessState; - List get data; + List get data => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $SuccessStateCopyWith get copyWith; + $SuccessStateCopyWith get copyWith => + throw _privateConstructorUsedError; } /// @nodoc @@ -224,17 +224,21 @@ class _$ErrorStateCopyWithImpl<$Res> extends _$MyApiStateCopyWithImpl<$Res> @override $Res call({ - Object errorMsg = freezed, + Object? errorMsg = freezed, }) { return _then(ErrorState( - errorMsg == freezed ? _value.errorMsg : errorMsg as String, + errorMsg == freezed + ? _value.errorMsg + : errorMsg // ignore: cast_nullable_to_non_nullable + as String, )); } } /// @nodoc + class _$ErrorState implements ErrorState { - _$ErrorState(this.errorMsg) : assert(errorMsg != null); + _$ErrorState(this.errorMsg); @override final String errorMsg; @@ -264,26 +268,22 @@ class _$ErrorState implements ErrorState { @override @optionalTypeArgs - TResult when({ - @required TResult success(List data), - @required TResult error(String errorMsg), - @required TResult loading(), + TResult when({ + required TResult Function(List data) success, + required TResult Function(String errorMsg) error, + required TResult Function() loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return error(errorMsg); } @override @optionalTypeArgs - TResult maybeWhen({ - TResult success(List data), - TResult error(String errorMsg), - TResult loading(), - @required TResult orElse(), + TResult maybeWhen({ + TResult Function(List data)? success, + TResult Function(String errorMsg)? error, + TResult Function()? loading, + required TResult orElse(), }) { - assert(orElse != null); if (error != null) { return error(errorMsg); } @@ -292,26 +292,22 @@ class _$ErrorState implements ErrorState { @override @optionalTypeArgs - TResult map({ - @required TResult success(SuccessState value), - @required TResult error(ErrorState value), - @required TResult loading(LoadingState value), + TResult map({ + required TResult Function(SuccessState value) success, + required TResult Function(ErrorState value) error, + required TResult Function(LoadingState value) loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return error(this); } @override @optionalTypeArgs - TResult maybeMap({ - TResult success(SuccessState value), - TResult error(ErrorState value), - TResult loading(LoadingState value), - @required TResult orElse(), + TResult maybeMap({ + TResult Function(SuccessState value)? success, + TResult Function(ErrorState value)? error, + TResult Function(LoadingState value)? loading, + required TResult orElse(), }) { - assert(orElse != null); if (error != null) { return error(this); } @@ -322,9 +318,10 @@ class _$ErrorState implements ErrorState { abstract class ErrorState implements MyApiState { factory ErrorState(String errorMsg) = _$ErrorState; - String get errorMsg; + String get errorMsg => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $ErrorStateCopyWith get copyWith; + $ErrorStateCopyWith get copyWith => + throw _privateConstructorUsedError; } /// @nodoc @@ -346,6 +343,7 @@ class _$LoadingStateCopyWithImpl<$Res> extends _$MyApiStateCopyWithImpl<$Res> } /// @nodoc + class _$LoadingState implements LoadingState { _$LoadingState(); @@ -364,26 +362,22 @@ class _$LoadingState implements LoadingState { @override @optionalTypeArgs - TResult when({ - @required TResult success(List data), - @required TResult error(String errorMsg), - @required TResult loading(), + TResult when({ + required TResult Function(List data) success, + required TResult Function(String errorMsg) error, + required TResult Function() loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return loading(); } @override @optionalTypeArgs - TResult maybeWhen({ - TResult success(List data), - TResult error(String errorMsg), - TResult loading(), - @required TResult orElse(), + TResult maybeWhen({ + TResult Function(List data)? success, + TResult Function(String errorMsg)? error, + TResult Function()? loading, + required TResult orElse(), }) { - assert(orElse != null); if (loading != null) { return loading(); } @@ -392,26 +386,22 @@ class _$LoadingState implements LoadingState { @override @optionalTypeArgs - TResult map({ - @required TResult success(SuccessState value), - @required TResult error(ErrorState value), - @required TResult loading(LoadingState value), + TResult map({ + required TResult Function(SuccessState value) success, + required TResult Function(ErrorState value) error, + required TResult Function(LoadingState value) loading, }) { - assert(success != null); - assert(error != null); - assert(loading != null); return loading(this); } @override @optionalTypeArgs - TResult maybeMap({ - TResult success(SuccessState value), - TResult error(ErrorState value), - TResult loading(LoadingState value), - @required TResult orElse(), + TResult maybeMap({ + TResult Function(SuccessState value)? success, + TResult Function(ErrorState value)? error, + TResult Function(LoadingState value)? loading, + required TResult orElse(), }) { - assert(orElse != null); if (loading != null) { return loading(this); } diff --git a/lib/routes/data/myapistate.dart b/lib/routes/data/myapistate.dart new file mode 100644 index 00000000..847d25ab --- /dev/null +++ b/lib/routes/data/myapistate.dart @@ -0,0 +1,12 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'myapistate.freezed.dart'; +part 'myapistate.g.dart'; + +@freezed +class MyApiState with _$MyApiState { + factory MyApiState() = _MyApiState; + + factory MyApiState.fromJson(Map json) => + _$MyApiStateFromJson(json); +} diff --git a/lib/routes/data/myapistate.freezed.dart b/lib/routes/data/myapistate.freezed.dart new file mode 100644 index 00000000..b353d6eb --- /dev/null +++ b/lib/routes/data/myapistate.freezed.dart @@ -0,0 +1,106 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides + +part of 'myapistate.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +MyApiState _$MyApiStateFromJson(Map json) { + return _MyApiState.fromJson(json); +} + +/// @nodoc +class _$MyApiStateTearOff { + const _$MyApiStateTearOff(); + + _MyApiState call() { + return _MyApiState(); + } + + MyApiState fromJson(Map json) { + return MyApiState.fromJson(json); + } +} + +/// @nodoc +const $MyApiState = _$MyApiStateTearOff(); + +/// @nodoc +mixin _$MyApiState { + Map toJson() => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $MyApiStateCopyWith<$Res> { + factory $MyApiStateCopyWith( + MyApiState value, $Res Function(MyApiState) then) = + _$MyApiStateCopyWithImpl<$Res>; +} + +/// @nodoc +class _$MyApiStateCopyWithImpl<$Res> implements $MyApiStateCopyWith<$Res> { + _$MyApiStateCopyWithImpl(this._value, this._then); + + final MyApiState _value; + // ignore: unused_field + final $Res Function(MyApiState) _then; +} + +/// @nodoc +abstract class _$MyApiStateCopyWith<$Res> { + factory _$MyApiStateCopyWith( + _MyApiState value, $Res Function(_MyApiState) then) = + __$MyApiStateCopyWithImpl<$Res>; +} + +/// @nodoc +class __$MyApiStateCopyWithImpl<$Res> extends _$MyApiStateCopyWithImpl<$Res> + implements _$MyApiStateCopyWith<$Res> { + __$MyApiStateCopyWithImpl( + _MyApiState _value, $Res Function(_MyApiState) _then) + : super(_value, (v) => _then(v as _MyApiState)); + + @override + _MyApiState get _value => super._value as _MyApiState; +} + +/// @nodoc +@JsonSerializable() +class _$_MyApiState implements _MyApiState { + _$_MyApiState(); + + factory _$_MyApiState.fromJson(Map json) => + _$_$_MyApiStateFromJson(json); + + @override + String toString() { + return 'MyApiState()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || (other is _MyApiState); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + Map toJson() { + return _$_$_MyApiStateToJson(this); + } +} + +abstract class _MyApiState implements MyApiState { + factory _MyApiState() = _$_MyApiState; + + factory _MyApiState.fromJson(Map json) = + _$_MyApiState.fromJson; +} diff --git a/lib/routes/data/myapistate.g.dart b/lib/routes/data/myapistate.g.dart new file mode 100644 index 00000000..2cbbec9c --- /dev/null +++ b/lib/routes/data/myapistate.g.dart @@ -0,0 +1,14 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'myapistate.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_MyApiState _$_$_MyApiStateFromJson(Map json) { + return _$_MyApiState(); +} + +Map _$_$_MyApiStateToJson(_$_MyApiState instance) => + {}; diff --git a/lib/routes/data/todo_item.dart b/lib/routes/data/todo_item.dart index 03e8fdc2..09e104ad 100644 --- a/lib/routes/data/todo_item.dart +++ b/lib/routes/data/todo_item.dart @@ -6,7 +6,7 @@ part 'todo_item.g.dart'; @HiveType(typeId: 0) class TodoItem extends HiveObject { @HiveField(0) - int id; + int? id; @HiveField(1) String content; @HiveField(2) @@ -14,8 +14,12 @@ class TodoItem extends HiveObject { @HiveField(3) final DateTime createdAt; - TodoItem({this.id, this.content, this.isDone = false, DateTime createdAt}) - : this.createdAt = createdAt ?? DateTime.now(); + TodoItem({ + this.id, + required this.content, + this.isDone = false, + DateTime? createdAt, + }) : this.createdAt = createdAt ?? DateTime.now(); @override String toString() { diff --git a/lib/routes/data/todo_item.g.dart b/lib/routes/data/todo_item.g.dart index fa7be988..d48cb607 100644 --- a/lib/routes/data/todo_item.g.dart +++ b/lib/routes/data/todo_item.g.dart @@ -17,10 +17,10 @@ class TodoItemAdapter extends TypeAdapter { for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), }; return TodoItem( - id: fields[0] as int, + id: fields[0] as int?, content: fields[1] as String, isDone: fields[2] as bool, - createdAt: fields[3] as DateTime, + createdAt: fields[3] as DateTime?, ); } diff --git a/lib/routes/firebase_chatroom_ex.dart b/lib/routes/firebase_chatroom_ex.dart index e27a225d..f9c7dcb8 100644 --- a/lib/routes/firebase_chatroom_ex.dart +++ b/lib/routes/firebase_chatroom_ex.dart @@ -11,7 +11,7 @@ import './firebase_login_ex.dart' show kFirebaseAnalytics; // firebase json file, and add configuration lines in the gradle files. // C.f. this commit: https://github.com/X-Wei/flutter_catalog/commit/48792cbc0de62fc47e0e9ba2cd3718117f4d73d1. class FirebaseChatroomExample extends StatefulWidget { - const FirebaseChatroomExample({Key key}) : super(key: key); + const FirebaseChatroomExample({Key? key}) : super(key: key); @override _FirebaseChatroomExampleState createState() => @@ -19,8 +19,8 @@ class FirebaseChatroomExample extends StatefulWidget { } class _FirebaseChatroomExampleState extends State { - firebase_auth.User _user; - DatabaseReference _firebaseMsgDbRef; + firebase_auth.User? _user; + late DatabaseReference _firebaseMsgDbRef; final TextEditingController _textController = TextEditingController(); bool _isComposing = false; @@ -49,7 +49,7 @@ class _FirebaseChatroomExampleState extends State { scrollDirection: Axis.horizontal, child: Text(_user == null ? 'Chatting' - : 'Chatting as "${_user.displayName}"'), + : 'Chatting as "${_user!.displayName}"'), ), ), body: Center( @@ -91,7 +91,7 @@ class _FirebaseChatroomExampleState extends State { child: FirebaseAnimatedList( defaultChild: const Center(child: CircularProgressIndicator()), query: _firebaseMsgDbRef, - sort: (a, b) => b.key.compareTo(a.key), + sort: (a, b) => b.key!.compareTo(a.key!), padding: const EdgeInsets.all(8.0), reverse: true, itemBuilder: (BuildContext ctx, DataSnapshot snapshot, @@ -105,10 +105,11 @@ class _FirebaseChatroomExampleState extends State { // Returns the UI of one message from a data snapshot. Widget _messageFromSnapshot( DataSnapshot snapshot, Animation animation) { - final senderName = snapshot.value['senderName'] as String ?? '?? '; - final msgText = snapshot.value['text'] as String ?? '??'; - final sentTime = snapshot.value['timestamp'] as int ?? 0; - final senderPhotoUrl = snapshot.value['senderPhotoUrl'] as String; + final senderName = + snapshot.value['senderName'] as String? ?? '?? '; + final msgText = snapshot.value['text'] as String? ?? '??'; + final sentTime = snapshot.value['timestamp'] as int? ?? 0; + final senderPhotoUrl = snapshot.value['senderPhotoUrl'] as String?; final messageUI = Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Row( @@ -214,9 +215,9 @@ class _FirebaseChatroomExampleState extends State { }); // Send message to firebase realtime database. _firebaseMsgDbRef.push().set({ - 'senderId': this._user.uid, - 'senderName': this._user.displayName, - 'senderPhotoUrl': this._user.photoURL, + 'senderId': this._user!.uid, + 'senderName': this._user!.displayName, + 'senderPhotoUrl': this._user!.photoURL, 'text': text, 'timestamp': DateTime.now().millisecondsSinceEpoch, }); diff --git a/lib/routes/firebase_login_ex.dart b/lib/routes/firebase_login_ex.dart index 20a363cf..4dc262e4 100644 --- a/lib/routes/firebase_login_ex.dart +++ b/lib/routes/firebase_login_ex.dart @@ -11,7 +11,7 @@ final kFirebaseAnalytics = FirebaseAnalytics(); // firebase json file, and add configuration lines in the gradle files. // C.f. this commit: https://github.com/X-Wei/flutter_catalog/commit/48792cbc0de62fc47e0e9ba2cd3718117f4d73d1. class FirebaseLoginExample extends StatefulWidget { - const FirebaseLoginExample({Key key}) : super(key: key); + const FirebaseLoginExample({Key? key}) : super(key: key); @override _FirebaseLoginExampleState createState() => _FirebaseLoginExampleState(); @@ -19,7 +19,7 @@ class FirebaseLoginExample extends StatefulWidget { class _FirebaseLoginExampleState extends State { final _auth = firebase_auth.FirebaseAuth.instance; - firebase_auth.User _user; + firebase_auth.User? _user; // If this._busy=true, the buttons are not clickable. This is to avoid // clicking buttons while a previous onTap function is not finished. bool _busy = false; @@ -28,7 +28,7 @@ class _FirebaseLoginExampleState extends State { void initState() { super.initState(); this._user = _auth.currentUser; - _auth.authStateChanges().listen((firebase_auth.User usr) { + _auth.authStateChanges().listen((firebase_auth.User? usr) { this._user = usr; debugPrint('user=$_user'); }); @@ -40,7 +40,7 @@ class _FirebaseLoginExampleState extends State { padding: const EdgeInsets.symmetric(vertical: 10.0), child: Text(_user == null ? 'You are not logged in.' - : 'You are logged in as "${_user.displayName}".'), + : 'You are logged in as "${_user!.displayName}".'), ); final googleLoginBtn = MaterialButton( color: Colors.blueAccent, @@ -49,7 +49,7 @@ class _FirebaseLoginExampleState extends State { : () async { setState(() => this._busy = true); final user = await this._googleSignIn(); - this._showUserProfilePage(user); + this._showUserProfilePage(user!); setState(() => this._busy = false); }, child: const Text('Log in with Google'), @@ -61,7 +61,7 @@ class _FirebaseLoginExampleState extends State { : () async { setState(() => this._busy = true); final user = await this._anonymousSignIn(); - this._showUserProfilePage(user); + this._showUserProfilePage(user!); setState(() => this._busy = false); }, child: const Text('Log in anonymously'), @@ -90,13 +90,13 @@ class _FirebaseLoginExampleState extends State { } // Sign in with Google. - Future _googleSignIn() async { + Future _googleSignIn() async { final curUser = this._user ?? _auth.currentUser; if (curUser != null && !curUser.isAnonymous) { return curUser; } final googleUser = await GoogleSignIn().signIn(); - final googleAuth = await googleUser.authentication; + final googleAuth = await googleUser!.authentication; final credential = firebase_auth.GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, @@ -109,14 +109,14 @@ class _FirebaseLoginExampleState extends State { } // Sign in Anonymously. - Future _anonymousSignIn() async { + Future _anonymousSignIn() async { final curUser = this._user ?? _auth.currentUser; if (curUser != null && curUser.isAnonymous) { return curUser; } final anonyUser = (await _auth.signInAnonymously()).user; - await anonyUser.updateProfile( - displayName: '${anonyUser.uid.substring(0, 5)}_Guest'); + await anonyUser! + .updateDisplayName('${anonyUser.uid.substring(0, 5)}_Guest'); await anonyUser.reload(); // Have to re-call `currentUser()` to make `updateProfile` work. // Cf. https://stackoverflow.com/questions/50986191/flutter-firebase-auth-updateprofile-method-is-not-working. @@ -158,10 +158,10 @@ class _FirebaseLoginExampleState extends State { title: const Text('Profile photo: '), trailing: user.photoURL != null ? CircleAvatar( - backgroundImage: NetworkImage(user.photoURL), + backgroundImage: NetworkImage(user.photoURL!), ) : CircleAvatar( - child: Text(user.displayName[0]), + child: Text(user.displayName![0]), ), ), ListTile( diff --git a/lib/routes/firebase_mlkit_ex.dart b/lib/routes/firebase_mlkit_ex.dart index 0156fe1f..88247ea6 100644 --- a/lib/routes/firebase_mlkit_ex.dart +++ b/lib/routes/firebase_mlkit_ex.dart @@ -1,33 +1,27 @@ import 'dart:io'; -import 'package:firebase_ml_vision/firebase_ml_vision.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:google_ml_kit/google_ml_kit.dart'; import 'package:image_picker/image_picker.dart'; import 'package:transparent_image/transparent_image.dart' show kTransparentImage; import 'package:flutter/material.dart'; -// NOTE: to add firebase support, first go to firebase console, generate the -// firebase json file, and add configuration lines in the gradle files. -// C.f. this commit: https://github.com/X-Wei/flutter_catalog/commit/48792cbc0de62fc47e0e9ba2cd3718117f4d73d1. - -// Adapted from the flutter firestore "babyname voter" codelab: -// https://codelabs.developers.google.com/codelabs/flutter-firebase/#0 -class FirebaseMLKitExample extends StatefulWidget { - const FirebaseMLKitExample({Key key}) : super(key: key); +class GoogleMLKitExample extends StatefulWidget { + const GoogleMLKitExample({Key? key}) : super(key: key); @override - _FirebaseMLKitExampleState createState() => _FirebaseMLKitExampleState(); + _GoogleMLKitExampleState createState() => _GoogleMLKitExampleState(); } -class _FirebaseMLKitExampleState extends State { - File _imageFile; +class _GoogleMLKitExampleState extends State { + File? _imageFile; String _mlResult = ''; final _picker = ImagePicker(); Future _pickImage() async { setState(() => this._imageFile = null); - final File imageFile = await showDialog( + final File? imageFile = await showDialog( context: context, builder: (ctx) => SimpleDialog( children: [ @@ -35,9 +29,11 @@ class _FirebaseMLKitExampleState extends State { leading: const Icon(Icons.camera_alt), title: const Text('Take picture'), onTap: () async { - final PickedFile pickedFile = - await _picker.getImage(source: ImageSource.camera); - Navigator.pop(ctx, File(pickedFile.path)); + final XFile? pickedFile = + await _picker.pickImage(source: ImageSource.camera); + if (pickedFile != null) { + Navigator.pop(ctx, File(pickedFile.path)); + } }, ), ListTile( @@ -45,9 +41,11 @@ class _FirebaseMLKitExampleState extends State { title: const Text('Pick from gallery'), onTap: () async { try { - final PickedFile pickedFile = - await _picker.getImage(source: ImageSource.gallery); - Navigator.pop(ctx, File(pickedFile.path)); + final XFile? pickedFile = + await _picker.pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + Navigator.pop(ctx, File(pickedFile.path)); + } } catch (e) { print(e); Navigator.pop(ctx, null); @@ -74,15 +72,13 @@ class _FirebaseMLKitExampleState extends State { return; } String result = ''; - final FirebaseVisionImage visionImage = - FirebaseVisionImage.fromFile(this._imageFile); - final ImageLabeler labelDetector = FirebaseVision.instance.imageLabeler(); - final List labels = - await labelDetector.processImage(visionImage); + final InputImage inputImage = InputImage.fromFile(this._imageFile!); + final ImageLabeler imageLabeler = GoogleMlKit.vision.imageLabeler(); + final List labels = await imageLabeler.processImage(inputImage); result += 'Detected ${labels.length} labels.\n'; for (final ImageLabel label in labels) { - final String text = label.text; - final String entityId = label.entityId; + final String text = label.label; + final int entityId = label.index; final double confidence = label.confidence; result += '\n#Label: $text($entityId), confidence=${confidence.toStringAsFixed(3)}'; @@ -98,20 +94,18 @@ class _FirebaseMLKitExampleState extends State { return; } String result = ''; - final FirebaseVisionImage visionImage = - FirebaseVisionImage.fromFile(this._imageFile); - final TextRecognizer textRecognizer = - FirebaseVision.instance.textRecognizer(); - final VisionText visionText = - await textRecognizer.processImage(visionImage); - final String text = visionText.text; + final InputImage inputImage = InputImage.fromFile(this._imageFile!); + final TextDetector textDetector = GoogleMlKit.vision.textDetector(); + final RecognisedText recognizedText = + await textDetector.processImage(inputImage); + final String text = recognizedText.text; debugPrint('Recognized text: "$text"'); - result += 'Detected ${visionText.blocks.length} text blocks.\n'; - for (final TextBlock block in visionText.blocks) { - final Rect boundingBox = block.boundingBox; + result += 'Detected ${recognizedText.blocks.length} text blocks.\n'; + for (final TextBlock block in recognizedText.blocks) { + final Rect boundingBox = block.rect; final List cornerPoints = block.cornerPoints; final String text = block.text; - final List languages = block.recognizedLanguages; + final List languages = block.recognizedLanguages; result += '\n# Text block:\n ' 'bbox=$boundingBox\n ' 'cornerPoints=$cornerPoints\n ' @@ -134,39 +128,20 @@ class _FirebaseMLKitExampleState extends State { return; } String result = ''; - final FirebaseVisionImage visionImage = - FirebaseVisionImage.fromFile(this._imageFile); - final BarcodeDetector barcodeDetector = - FirebaseVision.instance.barcodeDetector(); + final InputImage inputImage = InputImage.fromFile(this._imageFile!); + final BarcodeScanner barcodeScanner = GoogleMlKit.vision.barcodeScanner(); final List barcodes = - await barcodeDetector.detectInImage(visionImage); + await barcodeScanner.processImage(inputImage); result += 'Detected ${barcodes.length} barcodes.\n'; for (final Barcode barcode in barcodes) { - final Rect boundingBox = barcode.boundingBox; - final List cornerPoints = barcode.cornerPoints; - - final String rawValue = barcode.rawValue; - final valueType = barcode.valueType; + final Rect boundingBox = barcode.value.boundingBox!; + final String rawValue = barcode.value.rawValue!; + final valueType = barcode.type; result += '\n# Barcode:\n ' 'bbox=$boundingBox\n ' - 'cornerPoints=$cornerPoints\n ' 'rawValue=$rawValue\n ' - 'vlaueType=$valueType'; - // // See API reference for complete list of supported types - // switch (valueType) { - // case BarcodeValueType.wifi: - // final String ssid = barcode.wifi.ssid; - // final String password = barcode.wifi.password; - // final BarcodeWiFiEncryptionType type = barcode.wifi.encryptionType; - // break; - // case BarcodeValueType.url: - // final String title = barcode.url.title; - // final String url = barcode.url.url; - // break; - // default: - // break; - // } + 'type=$valueType'; } if (result.isNotEmpty) { setState(() => this._mlResult = result); @@ -179,42 +154,40 @@ class _FirebaseMLKitExampleState extends State { return; } String result = ''; - final FirebaseVisionImage visionImage = - FirebaseVisionImage.fromFile(this._imageFile); + final InputImage inputImage = InputImage.fromFile(this._imageFile!); const options = FaceDetectorOptions( enableLandmarks: true, enableClassification: true, enableTracking: true, ); - final FaceDetector faceDetector = - FirebaseVision.instance.faceDetector(options); - final List faces = await faceDetector.processImage(visionImage); + final FaceDetector faceDetector = GoogleMlKit.vision.faceDetector(options); + final List faces = await faceDetector.processImage(inputImage); result += 'Detected ${faces.length} faces.\n'; for (final Face face in faces) { final Rect boundingBox = face.boundingBox; // Head is rotated to the right rotY degrees - final double rotY = face.headEulerAngleY; + final double rotY = face.headEulerAngleY!; // Head is tilted sideways rotZ degrees - final double rotZ = face.headEulerAngleZ; + final double rotZ = face.headEulerAngleZ!; result += '\n# Face:\n ' 'bbox=$boundingBox\n ' 'rotY=$rotY\n ' 'rotZ=$rotZ\n '; // If landmark detection was enabled with FaceDetectorOptions (mouth, ears, // eyes, cheeks, and nose available): - final FaceLandmark leftEar = face.getLandmark(FaceLandmarkType.leftEar); + final FaceLandmark? leftEar = face.getLandmark(FaceLandmarkType.leftEar); if (leftEar != null) { final Offset leftEarPos = leftEar.position; result += 'leftEarPos=$leftEarPos\n '; } // If classification was enabled with FaceDetectorOptions: if (face.smilingProbability != null) { - final double smileProb = face.smilingProbability; + final double smileProb = face.smilingProbability!; result += 'smileProb=${smileProb.toStringAsFixed(3)}\n '; } // If face tracking was enabled with FaceDetectorOptions: if (face.trackingId != null) { - final int id = face.trackingId; + final int id = face.trackingId!; result += 'id=$id\n '; } } @@ -234,7 +207,7 @@ class _FirebaseMLKitExampleState extends State { else FadeInImage( placeholder: MemoryImage(kTransparentImage), - image: FileImage(this._imageFile), + image: FileImage(this._imageFile!), // Image.file(, fit: BoxFit.contain), ), SingleChildScrollView( diff --git a/lib/routes/firebase_vote_ex.dart b/lib/routes/firebase_vote_ex.dart index 3774116e..4b05cae9 100644 --- a/lib/routes/firebase_vote_ex.dart +++ b/lib/routes/firebase_vote_ex.dart @@ -4,6 +4,8 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; +typedef JsonMap = Map; + // NOTE: to add firebase support, first go to firebase console, generate the // firebase json file, and add configuration lines in the gradle files. // C.f. this commit: https://github.com/X-Wei/flutter_catalog/commit/48792cbc0de62fc47e0e9ba2cd3718117f4d73d1. @@ -11,14 +13,14 @@ import 'package:shared_preferences/shared_preferences.dart'; // Adapted from the flutter firestore "babyname voter" codelab: // https://codelabs.developers.google.com/codelabs/flutter-firebase/#0 class FirebaseVoteExample extends StatefulWidget { - const FirebaseVoteExample({Key key}) : super(key: key); + const FirebaseVoteExample({Key? key}) : super(key: key); @override _FirebaseVoteExampleState createState() => _FirebaseVoteExampleState(); } class _FirebaseVoteExampleState extends State { // We use SharedPreferences to keep track of which languages are voted. - SharedPreferences _preferences; + late SharedPreferences _preferences; static const kVotedPreferenceKeyPrefx = 'AlreadyVotedFor_'; @override @@ -32,7 +34,7 @@ class _FirebaseVoteExampleState extends State { @override Widget build(BuildContext context) { return Center( - child: StreamBuilder( + child: StreamBuilder>( // In firestore console I added a "language_voting" collection. stream: FirebaseFirestore.instance .collection('language_voting') @@ -41,7 +43,7 @@ class _FirebaseVoteExampleState extends State { if (!snapshot.hasData) { return const LinearProgressIndicator(); } else { - final List<_LangaugeVotingRecord> records = snapshot.data.docs + final List<_LangaugeVotingRecord> records = snapshot.data!.docs .map((snapshot) => _LangaugeVotingRecord.fromSnapshot(snapshot)) .toList() ..sort((record1, record2) => record2.votes - record1.votes); @@ -112,7 +114,7 @@ class _FirebaseVoteExampleState extends State { (transaction) async { try { final freshSnapshot = - await transaction.get(record.firestoreDocReference); + await transaction.get(record.firestoreDocReference); // Get the most fresh record. final freshRecord = _LangaugeVotingRecord.fromSnapshot(freshSnapshot); @@ -142,17 +144,17 @@ class _LangaugeVotingRecord { final String language; final int votes; // Reference to this record as a firestore document. - final DocumentReference firestoreDocReference; + final DocumentReference firestoreDocReference; - _LangaugeVotingRecord.fromMap(Map map, - {@required this.firestoreDocReference}) + _LangaugeVotingRecord.fromMap(JsonMap map, + {required this.firestoreDocReference}) : assert(map['language'] != null && map['language'] is String), assert(map['votes'] != null && map['votes'] is int), language = map['language'] as String, votes = map['votes'] as int; - _LangaugeVotingRecord.fromSnapshot(DocumentSnapshot snapshot) - : this.fromMap(snapshot.data(), + _LangaugeVotingRecord.fromSnapshot(DocumentSnapshot snapshot) + : this.fromMap(snapshot.data()!, firestoreDocReference: snapshot.reference); @override diff --git a/lib/routes/layouts_container_padding_center_ex.dart b/lib/routes/layouts_container_padding_center_ex.dart index e88f6973..b8b475b5 100644 --- a/lib/routes/layouts_container_padding_center_ex.dart +++ b/lib/routes/layouts_container_padding_center_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class ContainerExample extends StatelessWidget { - const ContainerExample({Key key}) : super(key: key); + const ContainerExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/layouts_expanded_ex.dart b/lib/routes/layouts_expanded_ex.dart index 221ec569..b90552a1 100644 --- a/lib/routes/layouts_expanded_ex.dart +++ b/lib/routes/layouts_expanded_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class ExpandedExample extends StatelessWidget { - const ExpandedExample({Key key}) : super(key: key); + const ExpandedExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/layouts_fractionally_sizedbox_ex.dart b/lib/routes/layouts_fractionally_sizedbox_ex.dart index 6a5f36a5..4ed5e136 100644 --- a/lib/routes/layouts_fractionally_sizedbox_ex.dart +++ b/lib/routes/layouts_fractionally_sizedbox_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class FractionallySizedBoxExample extends StatelessWidget { - const FractionallySizedBoxExample({Key key}) : super(key: key); + const FractionallySizedBoxExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/layouts_row_col_ex.dart b/lib/routes/layouts_row_col_ex.dart index cb3797c1..bb52dbcb 100644 --- a/lib/routes/layouts_row_col_ex.dart +++ b/lib/routes/layouts_row_col_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Inspired by bizz84's layout demo: // https://github.com/bizz84/layout-demo-flutter class RowColExample extends StatefulWidget { - const RowColExample({Key key}) : super(key: key); + const RowColExample({Key? key}) : super(key: key); @override _RowColExampleState createState() => _RowColExampleState(); } @@ -57,8 +57,8 @@ class _RowColExampleState extends State { Radio( value: true, groupValue: this._isRow, - onChanged: (bool value) { - setState(() => this._isRow = value); + onChanged: (bool? value) { + if (value != null) setState(() => this._isRow = value); }), const Text('Row'), ], @@ -68,8 +68,8 @@ class _RowColExampleState extends State { Radio( value: false, groupValue: this._isRow, - onChanged: (bool value) { - setState(() => this._isRow = value); + onChanged: (bool? value) { + if (value != null) setState(() => this._isRow = value); }), const Text('Column'), ], @@ -80,7 +80,7 @@ class _RowColExampleState extends State { title: const Text('mainAxisSize:'), trailing: DropdownButton( value: _mainAxisSize, - onChanged: (MainAxisSize newVal) { + onChanged: (MainAxisSize? newVal) { if (newVal != null) { setState(() => this._mainAxisSize = newVal); } @@ -98,7 +98,7 @@ class _RowColExampleState extends State { title: const Text('mainAxisAlignment:'), trailing: DropdownButton( value: _mainAxisAlignment, - onChanged: (MainAxisAlignment newVal) { + onChanged: (MainAxisAlignment? newVal) { if (newVal != null) { setState(() => this._mainAxisAlignment = newVal); } @@ -117,7 +117,7 @@ class _RowColExampleState extends State { title: const Text('crossAxisAlignment:'), trailing: DropdownButton( value: _crossAxisAlignment, - onChanged: (CrossAxisAlignment newVal) { + onChanged: (CrossAxisAlignment? newVal) { if (newVal != null) { setState(() => this._crossAxisAlignment = newVal); } diff --git a/lib/routes/layouts_stack_ex.dart b/lib/routes/layouts_stack_ex.dart index a4cce252..c3ab4cd6 100644 --- a/lib/routes/layouts_stack_ex.dart +++ b/lib/routes/layouts_stack_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Inspired by bizz84's layout demo: // https://github.com/bizz84/layout-demo-flutter class StackExample extends StatefulWidget { - const StackExample({Key key}) : super(key: key); + const StackExample({Key? key}) : super(key: key); @override _StackExampleState createState() => _StackExampleState(); @@ -50,7 +50,7 @@ class _StackExampleState extends State { title: const Text('alignmentDirectional:'), trailing: DropdownButton( value: _alignmentDirectional, - onChanged: (AlignmentDirectional newVal) { + onChanged: (AlignmentDirectional? newVal) { if (newVal != null) { setState(() => this._alignmentDirectional = newVal); } diff --git a/lib/routes/layouts_wrap_ex.dart b/lib/routes/layouts_wrap_ex.dart index 2ebef82f..f42079da 100644 --- a/lib/routes/layouts_wrap_ex.dart +++ b/lib/routes/layouts_wrap_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class WrapExample extends StatelessWidget { - const WrapExample({Key key}) : super(key: key); + const WrapExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/lists_datatable_ex.dart b/lib/routes/lists_datatable_ex.dart index 8a9ce85a..765e8cc6 100644 --- a/lib/routes/lists_datatable_ex.dart +++ b/lib/routes/lists_datatable_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Adapted from the data table demo in offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/data_table_demo.dart class DataTableExample extends StatefulWidget { - const DataTableExample({Key key}) : super(key: key); + const DataTableExample({Key? key}) : super(key: key); @override _DataTableExampleState createState() => _DataTableExampleState(); @@ -18,10 +18,10 @@ class _DataTableExampleState extends State { header: const Text('Nutrition'), rowsPerPage: _rowsPerPage, availableRowsPerPage: const [5, 10, 20], - onRowsPerPageChanged: (int value) { - setState(() { - _rowsPerPage = value; - }); + onRowsPerPageChanged: (int? value) { + if (value != null) { + setState(() => _rowsPerPage = value); + } }, columns: kTableColumns, source: DessertDataSource(), @@ -107,14 +107,15 @@ class DessertDataSource extends DataTableSource { ]; @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) { + onSelectChanged: (bool? value) { + if (value == null) return; if (dessert.selected != value) { _selectedCount += value ? 1 : -1; assert(_selectedCount >= 0); diff --git a/lib/routes/lists_expansion_tile_ex.dart b/lib/routes/lists_expansion_tile_ex.dart index fbd013e8..1d3f95c3 100644 --- a/lib/routes/lists_expansion_tile_ex.dart +++ b/lib/routes/lists_expansion_tile_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class ExpansionTileExample extends StatelessWidget { - const ExpansionTileExample({Key key}) : super(key: key); + const ExpansionTileExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/lists_grid_list_ex.dart b/lib/routes/lists_grid_list_ex.dart index 920c9e1a..d56070c2 100644 --- a/lib/routes/lists_grid_list_ex.dart +++ b/lib/routes/lists_grid_list_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class GridListExample extends StatelessWidget { - const GridListExample({Key key}) : super(key: key); + const GridListExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/lists_list_tile_ex.dart b/lib/routes/lists_list_tile_ex.dart index b6ff02e2..b133ce35 100644 --- a/lib/routes/lists_list_tile_ex.dart +++ b/lib/routes/lists_list_tile_ex.dart @@ -2,7 +2,7 @@ import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; class ListTileExample extends StatelessWidget { - const ListTileExample({Key key}) : super(key: key); + const ListTileExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/lists_listview_builder_ex.dart b/lib/routes/lists_listview_builder_ex.dart index b1c63159..983edac3 100644 --- a/lib/routes/lists_listview_builder_ex.dart +++ b/lib/routes/lists_listview_builder_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class ListViewBuilderExample extends StatelessWidget { - const ListViewBuilderExample({Key key}) : super(key: key); + const ListViewBuilderExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/lists_reorderable_ex.dart b/lib/routes/lists_reorderable_ex.dart index 71417ee5..41f8960e 100644 --- a/lib/routes/lists_reorderable_ex.dart +++ b/lib/routes/lists_reorderable_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Adapted from reorderable list demo in offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/reorderable_list_demo.dart class ReorderableListExample extends StatefulWidget { - const ReorderableListExample({Key key}) : super(key: key); + const ReorderableListExample({Key? key}) : super(key: key); @override State createState() { diff --git a/lib/routes/lists_slidable_tile_ex.dart b/lib/routes/lists_slidable_tile_ex.dart index ee01029f..8935059a 100644 --- a/lib/routes/lists_slidable_tile_ex.dart +++ b/lib/routes/lists_slidable_tile_ex.dart @@ -1,8 +1,10 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; class SlidableTileExample extends StatefulWidget { - const SlidableTileExample({Key key}) : super(key: key); + const SlidableTileExample({Key? key}) : super(key: key); @override _SlidableTileExampleState createState() => _SlidableTileExampleState(); @@ -15,7 +17,7 @@ class _SlidableTileExampleState extends State { 'SlidableScrollActionPane': SlidableScrollActionPane(), 'SlidableStrechActionPane': SlidableStrechActionPane(), }; - List _items; + late List _items; @override void initState() { super.initState(); @@ -92,7 +94,7 @@ class _SlidableTileExampleState extends State { ], ); }, - ); + ) as FutureOr; }, child: const SlidableDrawerDismissal(), ); diff --git a/lib/routes/lists_swipe_to_dismiss_ex.dart b/lib/routes/lists_swipe_to_dismiss_ex.dart index e54f9ec9..34327f57 100644 --- a/lib/routes/lists_swipe_to_dismiss_ex.dart +++ b/lib/routes/lists_swipe_to_dismiss_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class ListSwipeToDismissExample extends StatefulWidget { - const ListSwipeToDismissExample({Key key}) : super(key: key); + const ListSwipeToDismissExample({Key? key}) : super(key: key); @override State createState() { diff --git a/lib/routes/lists_wheel_scroll_view_ex.dart b/lib/routes/lists_wheel_scroll_view_ex.dart index cbde2830..143c3266 100644 --- a/lib/routes/lists_wheel_scroll_view_ex.dart +++ b/lib/routes/lists_wheel_scroll_view_ex.dart @@ -1,15 +1,13 @@ import 'package:flutter/material.dart'; class ListWheelViewExample extends StatefulWidget { - const ListWheelViewExample({Key key}) : super(key: key); + const ListWheelViewExample({Key? key}) : super(key: key); @override _ListWheelViewExampleState createState() => _ListWheelViewExampleState(); } class _ListWheelViewExampleState extends State { - - @override Widget build(BuildContext context) { return ListWheelScrollView.useDelegate( @@ -20,7 +18,10 @@ class _ListWheelViewExampleState extends State { return null; } return ListTile( - leading: Text("$index", style: TextStyle(fontSize: 50),), + leading: Text( + "$index", + style: TextStyle(fontSize: 50), + ), title: Text("Title $index"), subtitle: Text('Description here'), ); @@ -28,4 +29,3 @@ class _ListWheelViewExampleState extends State { ); } } - diff --git a/lib/routes/multimedia_edge_detection_ex.dart b/lib/routes/multimedia_edge_detection_ex.dart index 23973d4f..ddd3c47a 100644 --- a/lib/routes/multimedia_edge_detection_ex.dart +++ b/lib/routes/multimedia_edge_detection_ex.dart @@ -4,14 +4,14 @@ import 'package:edge_detection/edge_detection.dart'; import 'package:flutter/material.dart'; class EdgeDetectionExample extends StatefulWidget { - const EdgeDetectionExample({Key key}) : super(key: key); + const EdgeDetectionExample({Key? key}) : super(key: key); @override _EdgeDetectionExampleState createState() => _EdgeDetectionExampleState(); } class _EdgeDetectionExampleState extends State { - String _scannedImgPath; + String? _scannedImgPath; @override Widget build(BuildContext context) { return Column( @@ -23,9 +23,9 @@ class _EdgeDetectionExampleState extends State { onPressed: _doScan, ), if (_scannedImgPath != null) ...[ - Text(_scannedImgPath), + Text(_scannedImgPath!), Expanded( - child: Image.file(File(_scannedImgPath)), + child: Image.file(File(_scannedImgPath!)), ) ] ], @@ -38,6 +38,8 @@ class _EdgeDetectionExampleState extends State { /// !Unfortunately we cannot customize the behavior like loading image from /// !gallery or changing the saved image path. final imgPath = await EdgeDetection.detectEdge; - setState(() => _scannedImgPath = imgPath); + if (imgPath != null) { + setState(() => _scannedImgPath = imgPath); + } } } diff --git a/lib/routes/multimedia_extended_image_ex.dart b/lib/routes/multimedia_extended_image_ex.dart index e4375bec..55f5ee31 100644 --- a/lib/routes/multimedia_extended_image_ex.dart +++ b/lib/routes/multimedia_extended_image_ex.dart @@ -2,7 +2,7 @@ import 'package:extended_image/extended_image.dart'; import 'package:flutter/material.dart'; class ExtendedImageExample extends StatefulWidget { - const ExtendedImageExample({Key key}) : super(key: key); + const ExtendedImageExample({Key? key}) : super(key: key); @override _ExtendedImageExampleState createState() => _ExtendedImageExampleState(); @@ -34,17 +34,17 @@ class _ExtendedImageExampleState extends State { ElevatedButton.icon( label: const Text('Rotate right'), icon: const Icon(Icons.rotate_right), - onPressed: () => _editorKey.currentState.rotate(), + onPressed: () => _editorKey.currentState?.rotate(), ), ElevatedButton.icon( label: const Text('Rotate left'), icon: const Icon(Icons.rotate_left), - onPressed: () => _editorKey.currentState.rotate(right: false), + onPressed: () => _editorKey.currentState?.rotate(right: false), ), ElevatedButton.icon( label: const Text('Reset'), icon: const Icon(Icons.restore), - onPressed: () => _editorKey.currentState.reset(), + onPressed: () => _editorKey.currentState?.reset(), ), ], ), diff --git a/lib/routes/multimedia_image_picker_ex.dart b/lib/routes/multimedia_image_picker_ex.dart index 008e663f..7039a5bb 100644 --- a/lib/routes/multimedia_image_picker_ex.dart +++ b/lib/routes/multimedia_image_picker_ex.dart @@ -4,14 +4,14 @@ import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; class ImagePickerExample extends StatefulWidget { - const ImagePickerExample({Key key}) : super(key: key); + const ImagePickerExample({Key? key}) : super(key: key); @override _ImagePickerExampleState createState() => _ImagePickerExampleState(); } class _ImagePickerExampleState extends State { - File _imageFile; + File? _imageFile; final _picker = ImagePicker(); @override @@ -35,20 +35,22 @@ class _ImagePickerExampleState extends State { if (this._imageFile == null) const Placeholder() else - Image.file(this._imageFile), + Image.file(this._imageFile!), ], ); } Future _pickImageFromGallery() async { - final PickedFile pickedFile = - await _picker.getImage(source: ImageSource.gallery); - setState(() => this._imageFile = File(pickedFile.path)); + final pickedFile = await _picker.pickImage(source: ImageSource.gallery); + if (pickedFile != null) { + setState(() => this._imageFile = File(pickedFile.path)); + } } Future _pickImageFromCamera() async { - final PickedFile pickedFile = - await _picker.getImage(source: ImageSource.camera); - setState(() => this._imageFile = File(pickedFile.path)); + final pickedFile = await _picker.pickImage(source: ImageSource.camera); + if (pickedFile != null) { + setState(() => this._imageFile = File(pickedFile.path)); + } } } diff --git a/lib/routes/multimedia_image_plugin_ex.dart b/lib/routes/multimedia_image_plugin_ex.dart index 4d6a02f8..1796d1fe 100644 --- a/lib/routes/multimedia_image_plugin_ex.dart +++ b/lib/routes/multimedia_image_plugin_ex.dart @@ -5,7 +5,7 @@ import 'package:flutter/services.dart'; import 'package:image/image.dart' as image_pkg; class ImagePluginExample extends StatelessWidget { - const ImagePluginExample({Key key}) : super(key: key); + const ImagePluginExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -13,7 +13,7 @@ class ImagePluginExample extends StatelessWidget { future: getImgBytes(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { - final newImgBytes = manipulateImage(snapshot.data); + final newImgBytes = manipulateImage(snapshot.data!); return Center(child: Image.memory(newImgBytes)); } else { return const Center( @@ -25,7 +25,7 @@ class ImagePluginExample extends StatelessWidget { } Uint8List manipulateImage(Uint8List pngData) { - final img = image_pkg.readPng(pngData); + final img = image_pkg.readPng(pngData)!; image_pkg.drawString( img, /*font=*/ image_pkg.arial_48, diff --git a/lib/routes/multimedia_video_player_ex.dart b/lib/routes/multimedia_video_player_ex.dart index 7f5f9595..45afdc12 100644 --- a/lib/routes/multimedia_video_player_ex.dart +++ b/lib/routes/multimedia_video_player_ex.dart @@ -2,15 +2,15 @@ import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; class VideoPlayerExample extends StatefulWidget { - const VideoPlayerExample({Key key}) : super(key: key); + const VideoPlayerExample({Key? key}) : super(key: key); @override _VideoPlayerExampleState createState() => _VideoPlayerExampleState(); } class _VideoPlayerExampleState extends State { - VideoPlayerController _videoController; - VideoPlayerController _audioController; + late VideoPlayerController _videoController; + late VideoPlayerController _audioController; @override void initState() { @@ -35,14 +35,14 @@ class _VideoPlayerExampleState extends State { children: [ const ListTile(title: Text('Play online video:')), Center( - child: _videoController.value.initialized + child: _videoController.value.isInitialized ? _buildVideoPlayerUI() : const CircularProgressIndicator(), ), const Divider(), const ListTile(title: Text('Play online audio:')), Center( - child: _audioController.value.initialized + child: _audioController.value.isInitialized ? _buildAudioPlayerUI() : const LinearProgressIndicator(), ), diff --git a/lib/routes/nav_bottom_navbar_ex.dart b/lib/routes/nav_bottom_navbar_ex.dart index 59ab9247..bd447935 100644 --- a/lib/routes/nav_bottom_navbar_ex.dart +++ b/lib/routes/nav_bottom_navbar_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class BottomNavigationBarExample extends StatefulWidget { - const BottomNavigationBarExample({Key key}) : super(key: key); + const BottomNavigationBarExample({Key? key}) : super(key: key); @override State createState() => _BottomNavigationBarExampleState(); diff --git a/lib/routes/nav_bottom_sheet_ex.dart b/lib/routes/nav_bottom_sheet_ex.dart index f8e11cee..f01c42f2 100644 --- a/lib/routes/nav_bottom_sheet_ex.dart +++ b/lib/routes/nav_bottom_sheet_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class BottomSheetExample extends StatefulWidget { - const BottomSheetExample({Key key}) : super(key: key); + const BottomSheetExample({Key? key}) : super(key: key); @override _BottomSheetExampleState createState() => _BottomSheetExampleState(); @@ -24,7 +24,7 @@ class _BottomSheetExampleState extends State { onPressed: () => this ._scaffoldKey .currentState - .showBottomSheet((ctx) => _buildBottomSheet(ctx)), + ?.showBottomSheet((ctx) => _buildBottomSheet(ctx)), child: const Text('show bottom sheet'), ), ElevatedButton( diff --git a/lib/routes/nav_bottom_tabbar_ex.dart b/lib/routes/nav_bottom_tabbar_ex.dart index a627542e..0dd03e4b 100644 --- a/lib/routes/nav_bottom_tabbar_ex.dart +++ b/lib/routes/nav_bottom_tabbar_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class BottomTabbarExample extends StatefulWidget { - const BottomTabbarExample({Key key}) : super(key: key); + const BottomTabbarExample({Key? key}) : super(key: key); @override State createState() => _BottomTabbarExampleState(); @@ -9,7 +9,7 @@ class BottomTabbarExample extends StatefulWidget { class _BottomTabbarExampleState extends State with SingleTickerProviderStateMixin { - TabController _tabController; + late TabController _tabController; static const _kTabPages = [ Center(child: Icon(Icons.cloud, size: 64.0, color: Colors.teal)), diff --git a/lib/routes/nav_dialogs_ex.dart b/lib/routes/nav_dialogs_ex.dart index cfdf7cca..78eade80 100644 --- a/lib/routes/nav_dialogs_ex.dart +++ b/lib/routes/nav_dialogs_ex.dart @@ -4,7 +4,7 @@ import 'package:intl/intl.dart'; // Adapted from Eajy's flutter demo app: // https://github.com/Eajy/flutter_demo/blob/master/lib/route/homeDialogs.dart. class DialogsExample extends StatelessWidget { - const DialogsExample({Key key}) : super(key: key); + const DialogsExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -95,7 +95,7 @@ class DialogsExample extends StatelessWidget { showTimePicker( context: context, initialTime: TimeOfDay(hour: now.hour, minute: now.minute), - ).then((TimeOfDay value) { + ).then((TimeOfDay? value) { if (value != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -117,7 +117,7 @@ class DialogsExample extends StatelessWidget { initialDate: DateTime.now(), firstDate: DateTime(2018), lastDate: DateTime(2025), - ).then((DateTime value) { + ).then((DateTime? value) { if (value != null) { DateTime _fromDate = DateTime.now(); _fromDate = value; @@ -138,7 +138,7 @@ class DialogsExample extends StatelessWidget { context: context, firstDate: DateTime(2018), lastDate: DateTime(2025), - ).then((DateTimeRange value) { + ).then((DateTimeRange? value) { if (value != null) { DateTimeRange _fromRange = DateTimeRange(start: DateTime.now(), end: DateTime.now()); diff --git a/lib/routes/nav_draggable_scrollable_sheet_ex.dart b/lib/routes/nav_draggable_scrollable_sheet_ex.dart index ef7bfa8d..b27a86ef 100644 --- a/lib/routes/nav_draggable_scrollable_sheet_ex.dart +++ b/lib/routes/nav_draggable_scrollable_sheet_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class DraggableScrollableSheetExample extends StatelessWidget { - const DraggableScrollableSheetExample({Key key}) : super(key: key); + const DraggableScrollableSheetExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/nav_nav_drawer_header_ex.dart b/lib/routes/nav_nav_drawer_header_ex.dart index 59284376..41154198 100644 --- a/lib/routes/nav_nav_drawer_header_ex.dart +++ b/lib/routes/nav_nav_drawer_header_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class NavDrawerExample extends StatelessWidget { - const NavDrawerExample({Key key}) : super(key: key); + const NavDrawerExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/nav_pageselector_ex.dart b/lib/routes/nav_pageselector_ex.dart index 35f5cbad..d76d26d8 100644 --- a/lib/routes/nav_pageselector_ex.dart +++ b/lib/routes/nav_pageselector_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class PageSelectorExample extends StatelessWidget { - const PageSelectorExample({Key key}) : super(key: key); + const PageSelectorExample({Key? key}) : super(key: key); static const kIcons = [ Icon(Icons.event), @@ -28,7 +28,7 @@ class PageSelectorExample extends StatelessWidget { child: IconTheme( data: IconThemeData( size: 128.0, - color: Theme.of(context).accentColor, + color: Theme.of(context).colorScheme.secondary, ), child: const TabBarView(children: kIcons), ), @@ -36,7 +36,7 @@ class PageSelectorExample extends StatelessWidget { ElevatedButton( onPressed: () { final TabController controller = - DefaultTabController.of(context); + DefaultTabController.of(context)!; if (!controller.indexIsChanging) { controller.animateTo(kIcons.length - 1); } diff --git a/lib/routes/nav_routes_ex.dart b/lib/routes/nav_routes_ex.dart index 89df8add..574dc541 100644 --- a/lib/routes/nav_routes_ex.dart +++ b/lib/routes/nav_routes_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Adapted from Tensor Programming's multi-page app tutorial: // https://github.com/tensor-programming/dart_flutter_multi_page_app. class RoutesExample extends StatelessWidget { - const RoutesExample({Key key}) : super(key: key); + const RoutesExample({Key? key}) : super(key: key); /// Route name is useful for navigating between routes. /// ! Note: in the Flutter Catalog each example's names are class names @@ -16,7 +16,7 @@ class RoutesExample extends StatelessWidget { @override Widget build(BuildContext context) { - debugPrint('RouteName=${ModalRoute.of(context).settings.name}'); + debugPrint('RouteName=${ModalRoute.of(context)?.settings.name}'); return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, diff --git a/lib/routes/nav_tabs_ex.dart b/lib/routes/nav_tabs_ex.dart index 00599f17..daf21c1d 100644 --- a/lib/routes/nav_tabs_ex.dart +++ b/lib/routes/nav_tabs_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class TabsExample extends StatelessWidget { - const TabsExample({Key key}) : super(key: key); + const TabsExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/networking_googlebooks_ex.dart b/lib/routes/networking_googlebooks_ex.dart index a57dcbe7..fbf9968a 100644 --- a/lib/routes/networking_googlebooks_ex.dart +++ b/lib/routes/networking_googlebooks_ex.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class RestApiGoogleBooksExample extends StatefulWidget { - const RestApiGoogleBooksExample({Key key}) : super(key: key); + const RestApiGoogleBooksExample({Key? key}) : super(key: key); @override _RestApiGoogleBooksExampleState createState() => @@ -12,7 +12,7 @@ class RestApiGoogleBooksExample extends StatefulWidget { } class _RestApiGoogleBooksExampleState extends State { - TextEditingController _queryController; + late TextEditingController _queryController; List<_MyBook> _books = []; bool _pending = false; @@ -75,7 +75,7 @@ class _RestApiGoogleBooksExampleState extends State { queryParameters: {'q': query}, ); print('uri=$uri'); // https://www.googleapis.com/books/v1/volumes?q=$query - final http.Response response = await http.get(uri.toString()); + final http.Response response = await http.get(uri); if (response.statusCode == 200) { return _MyBook.parseFromJsonStr(response.body); } else { @@ -105,23 +105,23 @@ class _MyBook { final String title; final String authors; final String description; - final String thumbnailUrl; + final String? thumbnailUrl; _MyBook( this.id, this.title, this.authors, this.description, this.thumbnailUrl); Widget get thumbnail => this.thumbnailUrl != null - ? Image.network(this.thumbnailUrl) + ? Image.network(this.thumbnailUrl!) : CircleAvatar(child: Text(this.title[0])); _MyBook.fromJson(Map jsonMap) : id = jsonMap['id'] as String, title = jsonMap['volumeInfo']['title'] as String, authors = (jsonMap['volumeInfo']['authors'] as List).join(', '), - description = jsonMap['volumeInfo']['description'] as String ?? + description = jsonMap['volumeInfo']['description'] as String? ?? '', thumbnailUrl = - jsonMap['volumeInfo']['imageLinks']['smallThumbnail'] as String; + jsonMap['volumeInfo']['imageLinks']['smallThumbnail'] as String?; static List<_MyBook> parseFromJsonStr(String jsonStr) { final json = jsonDecode(jsonStr); diff --git a/lib/routes/networking_hacker_news_ex.dart b/lib/routes/networking_hacker_news_ex.dart index 0c34dc77..f18e11ab 100644 --- a/lib/routes/networking_hacker_news_ex.dart +++ b/lib/routes/networking_hacker_news_ex.dart @@ -7,7 +7,7 @@ import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart' as url_launcher; class RestApiHackerNewsExample extends StatefulWidget { - const RestApiHackerNewsExample({Key key}) : super(key: key); + const RestApiHackerNewsExample({Key? key}) : super(key: key); @override _RestApiHackerNewsExampleState createState() => @@ -51,8 +51,9 @@ class _RestApiHackerNewsExampleState extends State { child: const CircularProgressIndicator(), ); } - final hnArticle = MyHackerNewsArticle.fromJson(json - .decode(snapshot.data) as Map); + final hnArticle = MyHackerNewsArticle.fromJson( + json.decode(snapshot.data!) + as Map); return this._articleListTile(hnArticle); }, ), @@ -67,7 +68,8 @@ class _RestApiHackerNewsExampleState extends State { // Fetches the list of latest article Ids from '/v0/newstories.json'. Future _getLatestArticleIds() async { - const url = 'https://hacker-news.firebaseio.com/v0/newstories.json'; + final url = + Uri.parse('https://hacker-news.firebaseio.com/v0/newstories.json'); final response = await http.get(url); if (response.statusCode == 200) { final List articleIds = @@ -82,7 +84,8 @@ class _RestApiHackerNewsExampleState extends State { // Gets the detail of an article by its id from '/v0/item/$id.json'. Future _getArticleById(int id) async { - final url = 'https://hacker-news.firebaseio.com/v0/item/$id.json'; + final url = + Uri.parse('https://hacker-news.firebaseio.com/v0/item/$id.json'); final response = await http.get(url); assert(response.statusCode == 200); return response.body; @@ -91,22 +94,22 @@ class _RestApiHackerNewsExampleState extends State { // Renders one article obj as a list tile. Widget _articleListTile(MyHackerNewsArticle article) { final formatter = DateFormat.yMd().add_jms(); - final createdAt = DateTime.fromMillisecondsSinceEpoch(article.time * 1000); + final createdAt = DateTime.fromMillisecondsSinceEpoch(article.time! * 1000); return ListTile( - title: Text(article.title), + title: Text(article.title!), subtitle: Text('${article.by} - ' '${formatter.format(createdAt)}'), trailing: IconButton( icon: const Icon(Icons.open_in_new), onPressed: () async { - if (await url_launcher.canLaunch(article.url)) { + if (await url_launcher.canLaunch(article.url!)) { Navigator.of(context).push( MaterialPageRoute( builder: (ctx) => WebviewScaffold( initialChild: const Center(child: CircularProgressIndicator()), - url: article.url, - appBar: AppBar(title: Text(article.title)), + url: article.url!, + appBar: AppBar(title: Text(article.title!)), ), ), ); @@ -119,14 +122,14 @@ class _RestApiHackerNewsExampleState extends State { /// This data class is generated from https://javiercbk.github.io/json_to_dart/. class MyHackerNewsArticle { - String by; - int descendants; - int id; - int score; - int time; - String title; - String type; - String url; + String? by; + int? descendants; + int? id; + int? score; + int? time; + String? title; + String? type; + String? url; MyHackerNewsArticle( {this.by, diff --git a/lib/routes/networking_rest_api_fetch_ex.dart b/lib/routes/networking_rest_api_fetch_ex.dart index 14047a8e..7e97cdfc 100644 --- a/lib/routes/networking_rest_api_fetch_ex.dart +++ b/lib/routes/networking_rest_api_fetch_ex.dart @@ -6,15 +6,15 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class RestApiFetchExample extends StatefulWidget { - const RestApiFetchExample({Key key}) : super(key: key); + const RestApiFetchExample({Key? key}) : super(key: key); @override _RestApiFetchExampleState createState() => _RestApiFetchExampleState(); } class _RestApiFetchExampleState extends State { - TextEditingController _urlController; - TextEditingController _apiTokenController; + late TextEditingController _urlController; + late TextEditingController _apiTokenController; String _responseBody = ''; String _error = ''; bool _pending = false; @@ -87,7 +87,7 @@ class _RestApiFetchExampleState extends State { setState(() => this._pending = true); try { final http.Response response = await http.get( - url, + Uri.parse(url), headers: {HttpHeaders.authorizationHeader: apiToken}, ); // Usually we will add code to convert the response body into our data diff --git a/lib/routes/networking_rest_api_send_ex.dart b/lib/routes/networking_rest_api_send_ex.dart index 46dbe4d9..eab6345b 100644 --- a/lib/routes/networking_rest_api_send_ex.dart +++ b/lib/routes/networking_rest_api_send_ex.dart @@ -4,16 +4,16 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class RestApiSendExample extends StatefulWidget { - const RestApiSendExample({Key key}) : super(key: key); + const RestApiSendExample({Key? key}) : super(key: key); @override _RestApiSendExampleState createState() => _RestApiSendExampleState(); } class _RestApiSendExampleState extends State { - TextEditingController _titleController; - TextEditingController _contentController; - TextEditingController _userIdController; + late TextEditingController _titleController; + late TextEditingController _contentController; + late TextEditingController _userIdController; String _responseBody = ''; String _error = ''; bool _pending = false; @@ -106,7 +106,7 @@ From https://jsonplaceholder.typicode.com/guide.html we see that the API expects setState(() => this._pending = true); try { final http.Response response = await http.post( - 'https://jsonplaceholder.typicode.com/posts', + Uri.parse('https://jsonplaceholder.typicode.com/posts'), headers: { 'Content-Type': 'application/json; charset=UTF-8', }, diff --git a/lib/routes/persistence_file_rw_ex.dart b/lib/routes/persistence_file_rw_ex.dart index 011a71fb..299e25d3 100644 --- a/lib/routes/persistence_file_rw_ex.dart +++ b/lib/routes/persistence_file_rw_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart' as path_provider; class FileReadWriteExample extends StatefulWidget { - const FileReadWriteExample({Key key}) : super(key: key); + const FileReadWriteExample({Key? key}) : super(key: key); @override _FileReadWriteExampleState createState() => _FileReadWriteExampleState(); diff --git a/lib/routes/persistence_hive_ex.dart b/lib/routes/persistence_hive_ex.dart index fdfedcc4..1e4054ce 100644 --- a/lib/routes/persistence_hive_ex.dart +++ b/lib/routes/persistence_hive_ex.dart @@ -35,7 +35,7 @@ class TodoItem extends HiveObject { } */ class HiveExample extends StatefulWidget { - const HiveExample({Key key}) : super(key: key); + const HiveExample({Key? key}) : super(key: key); @override _HiveExampleState createState() => _HiveExampleState(); @@ -45,7 +45,7 @@ class _HiveExampleState extends State { static const kHiveFolder = 'hive'; static const kHiveBoxName = 'todosBox'; - Future _initDbFuture; + late Future _initDbFuture; @override void initState() { diff --git a/lib/routes/persistence_preference_ex.dart b/lib/routes/persistence_preference_ex.dart index 3c0f99ea..f9a30f09 100644 --- a/lib/routes/persistence_preference_ex.dart +++ b/lib/routes/persistence_preference_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class SharedPreferenceExample extends StatefulWidget { - const SharedPreferenceExample({Key key}) : super(key: key); + const SharedPreferenceExample({Key? key}) : super(key: key); @override _SharedPreferenceExampleState createState() => @@ -10,7 +10,7 @@ class SharedPreferenceExample extends StatefulWidget { } class _SharedPreferenceExampleState extends State { - SharedPreferences _prefs; + SharedPreferences? _prefs; static const String kDemoNumberPrefKey = 'demo_number_pref'; static const String kDemoBooleanPrefKey = 'demo_boolean_pref'; int _numberPref = 0; @@ -58,24 +58,24 @@ class _SharedPreferenceExampleState extends State { // Loads number preference into this._numberPref. void _loadNumberPref() { setState(() { - this._numberPref = this._prefs.getInt(kDemoNumberPrefKey) ?? 0; + this._numberPref = this._prefs?.getInt(kDemoNumberPrefKey) ?? 0; }); } // Loads boolean preference into this._numberPref. void _loadBooleanPref() { setState(() { - this._boolPref = this._prefs.getBool(kDemoBooleanPrefKey) ?? false; + this._boolPref = this._prefs?.getBool(kDemoBooleanPrefKey) ?? false; }); } Future _setNumberPref(int val) async { - await this._prefs.setInt(kDemoNumberPrefKey, val); + await this._prefs?.setInt(kDemoNumberPrefKey, val); _loadNumberPref(); } Future _setBooleanPref(bool val) async { - await this._prefs.setBool(kDemoBooleanPrefKey, val); + await this._prefs?.setBool(kDemoBooleanPrefKey, val); _loadBooleanPref(); } } diff --git a/lib/routes/persistence_sembast_ex.dart b/lib/routes/persistence_sembast_ex.dart index c2a55f86..d5f3896e 100644 --- a/lib/routes/persistence_sembast_ex.dart +++ b/lib/routes/persistence_sembast_ex.dart @@ -7,12 +7,17 @@ import 'package:sembast/sembast_io.dart'; // Data class for the mini todo application. class TodoItem { - final int id; + final int? id; final String content; bool isDone; final DateTime createdAt; - TodoItem({this.id, this.content, this.isDone = false, this.createdAt}); + TodoItem({ + this.id, + required this.content, + this.isDone = false, + required this.createdAt, + }); TodoItem.fromJsonMap(Map map) : id = map['id'] as int, @@ -30,7 +35,7 @@ class TodoItem { } class SembastExample extends StatefulWidget { - const SembastExample({Key key}) : super(key: key); + const SembastExample({Key? key}) : super(key: key); @override _SembastExampleState createState() => _SembastExampleState(); @@ -40,9 +45,9 @@ class _SembastExampleState extends State { static const kDbFileName = 'sembast_ex.db'; static const kDbStoreName = 'example_store'; - Future _initDbFuture; - Database _db; - StoreRef> _store; + late Future _initDbFuture; + late Database _db; + late StoreRef> _store; List _todos = []; @override diff --git a/lib/routes/persistence_sqlite_ex.dart b/lib/routes/persistence_sqlite_ex.dart index ea3d509a..70aff056 100644 --- a/lib/routes/persistence_sqlite_ex.dart +++ b/lib/routes/persistence_sqlite_ex.dart @@ -8,14 +8,19 @@ import 'package:sqflite/sqflite.dart'; // Data class for the mini todo application. class TodoItem { - final int id; + final int? id; final String content; // SQLite doesn't supprot boolean. Use INTEGER/BIT (0/1 values). final bool isDone; // SQLite doesn't supprot DateTime. Store them as INTEGER (millisSinceEpoch). final DateTime createdAt; - TodoItem({this.id, this.content, this.isDone = false, this.createdAt}); + TodoItem({ + this.id, + required this.content, + this.isDone = false, + required this.createdAt, + }); TodoItem.fromJsonMap(Map map) : id = map['id'] as int, @@ -33,7 +38,7 @@ class TodoItem { } class SqliteExample extends StatefulWidget { - const SqliteExample({Key key}) : super(key: key); + const SqliteExample({Key? key}) : super(key: key); @override _SqliteExampleState createState() => _SqliteExampleState(); @@ -44,7 +49,7 @@ class _SqliteExampleState extends State { static const kDbTableName = 'example_tbl'; final AsyncMemoizer _memoizer = AsyncMemoizer(); - Database _db; + late Database _db; List _todos = []; // Opens a db local file. Creates the db table if it's not yet created. diff --git a/lib/routes/plugins_feature_discovery_ex.dart b/lib/routes/plugins_feature_discovery_ex.dart index 61b1f160..d1798b71 100644 --- a/lib/routes/plugins_feature_discovery_ex.dart +++ b/lib/routes/plugins_feature_discovery_ex.dart @@ -4,7 +4,7 @@ import 'package:english_words/english_words.dart' as english_words; import 'package:flutter/scheduler.dart'; class FeatureDiscoveryExample extends StatelessWidget { - const FeatureDiscoveryExample({Key key}) : super(key: key); + const FeatureDiscoveryExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -15,7 +15,7 @@ class FeatureDiscoveryExample extends StatelessWidget { } class _DemoPage extends StatefulWidget { - const _DemoPage({Key key}) : super(key: key); + const _DemoPage({Key? key}) : super(key: key); @override _DemoPageState createState() => _DemoPageState(); @@ -26,8 +26,8 @@ class _DemoPageState extends State<_DemoPage> { static const _kFeatureId2Sub = 'feature2_substract'; static const _kFeatureId3Refresh = 'feature3_refresh'; - List _strsToShow; - GlobalKey _ensureVisibleGlobalKey; + late List _strsToShow; + late GlobalKey _ensureVisibleGlobalKey; List _getRandomStrings() { return [ @@ -43,7 +43,7 @@ class _DemoPageState extends State<_DemoPage> { this._strsToShow = _getRandomStrings(); // !Show feature discovery right after the page is ready. SchedulerBinding.instance - .addPostFrameCallback((Duration duration) => _showDiscovery()); + ?.addPostFrameCallback((Duration duration) => _showDiscovery()); } @override @@ -82,8 +82,8 @@ class _DemoPageState extends State<_DemoPage> { 'Tap the refresh button to re-generate the random text list.'), backgroundColor: Theme.of(context).primaryColor, onOpen: () async { - WidgetsBinding.instance.addPostFrameCallback((Duration duration) { - _ensureVisibleGlobalKey.currentState.ensureVisible( + WidgetsBinding.instance?.addPostFrameCallback((Duration duration) { + _ensureVisibleGlobalKey.currentState?.ensureVisible( preciseAlignment: 0.5, duration: const Duration(milliseconds: 400), ); diff --git a/lib/routes/plugins_local_auth_ex.dart b/lib/routes/plugins_local_auth_ex.dart index e533924f..8c4d7a38 100644 --- a/lib/routes/plugins_local_auth_ex.dart +++ b/lib/routes/plugins_local_auth_ex.dart @@ -4,7 +4,7 @@ import 'package:transparent_image/transparent_image.dart' show kTransparentImage; class LocalAuthExample extends StatefulWidget { - const LocalAuthExample({Key key}) : super(key: key); + const LocalAuthExample({Key? key}) : super(key: key); @override _LocalAuthExampleState createState() => _LocalAuthExampleState(); @@ -12,7 +12,7 @@ class LocalAuthExample extends StatefulWidget { class _LocalAuthExampleState extends State { bool _authSuccess = false; - LocalAuthentication _localAuth; + late LocalAuthentication _localAuth; @override void initState() { @@ -35,8 +35,10 @@ class _LocalAuthExampleState extends State { // **NOTE**: for local auth to work, tha MainActivity needs to extend from // FlutterFragmentActivity, cf. https://stackoverflow.com/a/56605771. try { - final authSuccess = await this._localAuth.authenticateWithBiometrics( - localizedReason: 'Auth in to see hidden image'); + final authSuccess = await this._localAuth.authenticate( + biometricOnly: true, + localizedReason: 'Auth in to see hidden image', + ); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('authSuccess=$authSuccess')), ); diff --git a/lib/routes/plugins_markdown_ex.dart b/lib/routes/plugins_markdown_ex.dart index 41cfd5a6..9725a2af 100644 --- a/lib/routes/plugins_markdown_ex.dart +++ b/lib/routes/plugins_markdown_ex.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'package:markdown/markdown.dart' as md; -import 'package:syntax_highlighter/syntax_highlighter.dart' - show SyntaxHighlighterStyle, DartSyntaxHighlighter; +// import 'package:google_fonts/google_fonts.dart'; +// TODO: re-add syntax_highlighter when the package is migrated to null-safty. +// import 'package:syntax_highlighter/syntax_highlighter.dart' +// show SyntaxHighlighterStyle, DartSyntaxHighlighter; import 'package:url_launcher/url_launcher.dart'; const String _markdownSrc = ''' @@ -52,11 +53,12 @@ Enjoy! '''; class MarkdownExample extends StatelessWidget { - const MarkdownExample({Key key}) : super(key: key); + const MarkdownExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - Future _onTapLink(String text, String href, String title) async { + Future _onTapLink(String text, String? href, String title) async { + if (href == null) return; if (await canLaunch(href)) { launch(href); } else { @@ -73,7 +75,7 @@ class MarkdownExample extends StatelessWidget { data: _markdownSrc, onTapLink: _onTapLink, selectable: true, - syntaxHighlighter: _MyDartSyntaxHighligher(), + // syntaxHighlighter: _MyDartSyntaxHighligher(), //// We use [GitHub flavored Markdown]: https://github.github.com/gfm/. extensionSet: md.ExtensionSet( /*blockSyntaxes=*/ md.ExtensionSet.gitHubFlavored.blockSyntaxes, @@ -84,18 +86,18 @@ class MarkdownExample extends StatelessWidget { } } -/// Note: There is a package [syntax_highlighter] with [format] function, but -/// (at version=0.1.1) it doesn't extend the [flutter_markdown.SyntaxHighlighter] -/// class, thus cannot be used in [Markdown]. So here we add a custom wrapper. -/// TODO: create a pull request to the [syntax_highlighter] package. -class _MyDartSyntaxHighligher extends SyntaxHighlighter { - final highlighter = - DartSyntaxHighlighter(SyntaxHighlighterStyle.lightThemeStyle()); - @override - TextSpan format(String source) { - return TextSpan( - style: GoogleFonts.droidSansMono(), - children: [highlighter.format(source)], - ); - } -} +// /// Note: There is a package [syntax_highlighter] with [format] function, but +// /// (at version=0.1.1) it doesn't extend the [flutter_markdown.SyntaxHighlighter] +// /// class, thus cannot be used in [Markdown]. So here we add a custom wrapper. +// /// TODO: create a pull request to the [syntax_highlighter] package. +// class _MyDartSyntaxHighligher extends SyntaxHighlighter { +// final highlighter = +// DartSyntaxHighlighter(SyntaxHighlighterStyle.lightThemeStyle()); +// @override +// TextSpan format(String source) { +// return TextSpan( +// style: GoogleFonts.droidSansMono(), +// children: [highlighter.format(source)], +// ); +// } +// } diff --git a/lib/routes/plugins_shimmer_ex.dart b/lib/routes/plugins_shimmer_ex.dart index e7b4f2d3..b251dda8 100644 --- a/lib/routes/plugins_shimmer_ex.dart +++ b/lib/routes/plugins_shimmer_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; class ShimmerExample extends StatelessWidget { - const ShimmerExample({Key key}) : super(key: key); + const ShimmerExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -11,8 +11,8 @@ class ShimmerExample extends StatelessWidget { children: [ Shimmer.fromColors( // enabled: true, - baseColor: Colors.grey[400], - highlightColor: Colors.grey[100], + baseColor: Colors.grey[400]!, + highlightColor: Colors.grey[100]!, child: const ListTile( title: Text('Slide to unlock'), trailing: Icon(Icons.keyboard_arrow_right), @@ -21,8 +21,8 @@ class ShimmerExample extends StatelessWidget { const Divider(), Shimmer.fromColors( // enabled: true, - baseColor: Colors.grey[400], - highlightColor: Colors.grey[100], + baseColor: Colors.grey[400]!, + highlightColor: Colors.grey[100]!, child: ListView.separated( shrinkWrap: true, physics: const ClampingScrollPhysics(), diff --git a/lib/routes/plugins_webview_ex.dart b/lib/routes/plugins_webview_ex.dart index 72219828..a50d8b0f 100644 --- a/lib/routes/plugins_webview_ex.dart +++ b/lib/routes/plugins_webview_ex.dart @@ -3,14 +3,14 @@ import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; import 'package:url_launcher/url_launcher.dart' as url_launcher; class WebViewExample extends StatefulWidget { - const WebViewExample({Key key}) : super(key: key); + const WebViewExample({Key? key}) : super(key: key); @override _WebViewExampleState createState() => _WebViewExampleState(); } class _WebViewExampleState extends State { - TextEditingController _controller; + late TextEditingController _controller; @override void initState() { diff --git a/lib/routes/state_bloc_ex.dart b/lib/routes/state_bloc_ex.dart index 448add4a..102f8766 100644 --- a/lib/routes/state_bloc_ex.dart +++ b/lib/routes/state_bloc_ex.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; class BlocExample extends StatelessWidget { - const BlocExample({Key key}) : super(key: key); + const BlocExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -19,7 +19,7 @@ class _MyEvent { final bool isIncrement; final DateTime timestamp; - _MyEvent({@required this.isIncrement, DateTime timestamp}) + _MyEvent({required this.isIncrement, DateTime? timestamp}) : this.timestamp = timestamp ?? DateTime.now(); } @@ -73,10 +73,10 @@ class MyBlocProvider extends InheritedWidget { @override final Widget child; // ignore: overridden_fields - const MyBlocProvider({Key key, @required this.bloc, this.child}) + const MyBlocProvider({Key? key, required this.bloc, required this.child}) : super(key: key, child: child); - static MyBlocProvider of(BuildContext context) { + static MyBlocProvider? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType(); } @@ -150,7 +150,7 @@ class _AppRootWidget extends StatelessWidget { class _CounterAndButton extends StatelessWidget { @override Widget build(BuildContext context) { - final MyBloc bloc = MyBlocProvider.of(context).bloc; + final MyBloc bloc = MyBlocProvider.of(context)!.bloc; return Card( margin: const EdgeInsets.all(4.0).copyWith(top: 32.0, bottom: 32.0), color: Colors.white70, @@ -168,7 +168,7 @@ class _CounterAndButton extends StatelessWidget { print(snapshot.data); final state = snapshot.data; return Text( - '${state.counterValue}', + '${state!.counterValue}', style: Theme.of(context).textTheme.headline4, ); }, diff --git a/lib/routes/state_bloc_lib_ex.dart b/lib/routes/state_bloc_lib_ex.dart index ec169c13..7eb94bb1 100644 --- a/lib/routes/state_bloc_lib_ex.dart +++ b/lib/routes/state_bloc_lib_ex.dart @@ -4,7 +4,7 @@ import 'package:bloc/bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class BlocLibExample extends StatelessWidget { - const BlocLibExample({Key key}) : super(key: key); + const BlocLibExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -21,7 +21,7 @@ class _MyEvent { final bool isIncrement; final DateTime timestamp; - _MyEvent({@required this.isIncrement, DateTime timestamp}) + _MyEvent({required this.isIncrement, DateTime? timestamp}) : this.timestamp = timestamp ?? DateTime.now(); } @@ -122,8 +122,8 @@ class _CounterAndButton extends StatelessWidget { const Text('(child widget)'), // ###5. Access the state from child widget by wrapping the widget by // a BlocBuilder. - BlocBuilder( - cubit: BlocProvider.of(context), + BlocBuilder( + bloc: BlocProvider.of(context), builder: (context, _MyState state) { return Text( '${state.counter}', diff --git a/lib/routes/state_inherited_widget_ex.dart b/lib/routes/state_inherited_widget_ex.dart index f53673eb..d837f421 100644 --- a/lib/routes/state_inherited_widget_ex.dart +++ b/lib/routes/state_inherited_widget_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class InheritedWidgetExample extends StatelessWidget { - const InheritedWidgetExample({Key key}) : super(key: key); + const InheritedWidgetExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -20,7 +20,8 @@ class InheritedWidgetExample extends StatelessWidget { class MyInheritedWidget extends InheritedWidget { final _MyDemoAppState myState; - const MyInheritedWidget({Key key, Widget child, @required this.myState}) + const MyInheritedWidget( + {Key? key, required Widget child, required this.myState}) : super(key: key, child: child); @override @@ -29,7 +30,7 @@ class MyInheritedWidget extends InheritedWidget { return this.myState.counterValue != oldWidget.myState.counterValue; } - static MyInheritedWidget of(BuildContext context) { + static MyInheritedWidget? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType(); } } @@ -79,7 +80,7 @@ class _MyDemoAppState extends State<_MyDemoApp> { class _AppRootWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final rootWidgetsState = MyInheritedWidget.of(context).myState; + final rootWidgetsState = MyInheritedWidget.of(context)!.myState; return Card( elevation: 4.0, child: Column( @@ -106,7 +107,7 @@ class _CounterAndButton extends StatelessWidget { @override Widget build(BuildContext context) { // ###4. Retrieve parent widget's state using the static of() function. - final rootWidgetsState = MyInheritedWidget.of(context).myState; + final rootWidgetsState = MyInheritedWidget.of(context)!.myState; return Card( margin: const EdgeInsets.all(4.0).copyWith(bottom: 32.0), color: Colors.white70, diff --git a/lib/routes/state_provider_ex.dart b/lib/routes/state_provider_ex.dart index 62a4ca0b..2e690972 100644 --- a/lib/routes/state_provider_ex.dart +++ b/lib/routes/state_provider_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class ProviderExample extends StatelessWidget { - const ProviderExample({Key key}) : super(key: key); + const ProviderExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -115,7 +115,7 @@ class _CounterAndButton extends StatelessWidget { // Way 2 to get state up the tree: wrap a Consumer widget. Consumer<_MyCounterState>( builder: (BuildContext context, _MyCounterState value, - Widget child) { + Widget? child) { return IconButton( icon: const Icon(Icons.remove), onPressed: () => value.decrementCounter(), diff --git a/lib/routes/state_riverpod_freezed_ex.dart b/lib/routes/state_riverpod_freezed_ex.dart index ac44c012..faa66801 100644 --- a/lib/routes/state_riverpod_freezed_ex.dart +++ b/lib/routes/state_riverpod_freezed_ex.dart @@ -35,12 +35,12 @@ class MyApiModel extends StateNotifier { /// Note: in Resocoder's tutorial, he defined a "repository" class that abstracts /// the core logic of generating names (and have one provider depending on /// another provider). Here I don't have the "repository" abstraction layer. -final kMyApiModelProvider = StateNotifierProvider( +final kMyApiModelProvider = StateNotifierProvider( (ref) => MyApiModel(), ); class RiverpodFreezedExample extends StatelessWidget { - const RiverpodFreezedExample({Key key}) : super(key: key); + const RiverpodFreezedExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -116,7 +116,8 @@ class __DemoPageState extends State<_DemoPage> { onPressed: () { //! Use context.read(fooProvider) to access provider outside of //! `build()`. - final model = context.read(kMyApiModelProvider); + final model = + context.read(kMyApiModelProvider.notifier); model.generateRandomNames(this._n); }, ), @@ -126,7 +127,7 @@ class __DemoPageState extends State<_DemoPage> { ///! If we put the logic in build(), a snackbar will show every time ///! the widget builds ProviderListener( - provider: kMyApiModelProvider.state, + provider: kMyApiModelProvider, onChange: (context, state) { if (state is ErrorState) { ScaffoldMessenger.of(context).showSnackBar( @@ -141,7 +142,7 @@ class __DemoPageState extends State<_DemoPage> { ///! `ConsumerWidget`, there we have access to the `watch` function. child: Consumer( builder: (context, watch, child) { - final state = watch(kMyApiModelProvider.state); + final state = watch(kMyApiModelProvider); // ! With the sealed union by freezed, we can match on the possible // ! states and show different UI. return state.when( diff --git a/lib/routes/state_scoped_model_ex.dart b/lib/routes/state_scoped_model_ex.dart index 550d72ec..b69be1ea 100644 --- a/lib/routes/state_scoped_model_ex.dart +++ b/lib/routes/state_scoped_model_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:scoped_model/scoped_model.dart'; class ScopedModelExample extends StatelessWidget { - const ScopedModelExample({Key key}) : super(key: key); + const ScopedModelExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/state_state_notifier_freezed_ex.dart b/lib/routes/state_state_notifier_freezed_ex.dart index eba7279b..fe229cc6 100644 --- a/lib/routes/state_state_notifier_freezed_ex.dart +++ b/lib/routes/state_state_notifier_freezed_ex.dart @@ -32,7 +32,7 @@ class MyApiModel extends StateNotifier { } class StateNotifierFreezedExample extends StatelessWidget { - const StateNotifierFreezedExample({Key key}) : super(key: key); + const StateNotifierFreezedExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/widgets_buttons_ex.dart b/lib/routes/widgets_buttons_ex.dart index c7ab4320..7718d5e7 100644 --- a/lib/routes/widgets_buttons_ex.dart +++ b/lib/routes/widgets_buttons_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class ButtonsExample extends StatelessWidget { - const ButtonsExample({Key key}) : super(key: key); + const ButtonsExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/widgets_card_ex.dart b/lib/routes/widgets_card_ex.dart index 808f8372..03e97480 100644 --- a/lib/routes/widgets_card_ex.dart +++ b/lib/routes/widgets_card_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class CardExample extends StatelessWidget { - const CardExample({Key key}) : super(key: key); + const CardExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -84,7 +84,7 @@ class CardExample extends StatelessWidget { 'Card 4 (complex example)', style: Theme.of(context) .textTheme - .headline5 + .headline5! .copyWith(color: Colors.white), ), ), diff --git a/lib/routes/widgets_dropdown_button_ex.dart b/lib/routes/widgets_dropdown_button_ex.dart index 7eeeec56..58cec916 100644 --- a/lib/routes/widgets_dropdown_button_ex.dart +++ b/lib/routes/widgets_dropdown_button_ex.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // Inspired by dropdown buttons demo in offical flutter gallery: // https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/buttons_demo.dart class DropdownButtonExample extends StatefulWidget { - const DropdownButtonExample({Key key}) : super(key: key); + const DropdownButtonExample({Key? key}) : super(key: key); @override State createState() => _DropdownButtonExampleState(); @@ -34,8 +34,8 @@ class _DropdownButtonExampleState extends State { .toList(); String _btn1SelectedVal = 'One'; - String _btn2SelectedVal; - String _btn3SelectedVal; + String? _btn2SelectedVal; + late String _btn3SelectedVal; @override Widget build(BuildContext context) { @@ -46,10 +46,10 @@ class _DropdownButtonExampleState extends State { trailing: DropdownButton( // Must be one of items.value. value: _btn1SelectedVal, - onChanged: (String newValue) { - setState(() { - _btn1SelectedVal = newValue; - }); + onChanged: (String? newValue) { + if (newValue != null) { + setState(() => _btn1SelectedVal = newValue); + } }, items: this._dropDownMenuItems, ), @@ -59,10 +59,10 @@ class _DropdownButtonExampleState extends State { trailing: DropdownButton( value: _btn2SelectedVal, hint: const Text('Choose'), - onChanged: (String newValue) { - setState(() { - _btn2SelectedVal = newValue; - }); + onChanged: (String? newValue) { + if (newValue != null) { + setState(() => _btn2SelectedVal = newValue); + } }, items: _dropDownMenuItems, ), diff --git a/lib/routes/widgets_gradient_ex.dart b/lib/routes/widgets_gradient_ex.dart index f4adc21f..07922458 100644 --- a/lib/routes/widgets_gradient_ex.dart +++ b/lib/routes/widgets_gradient_ex.dart @@ -1,17 +1,18 @@ import 'dart:math' show pi; import 'package:flutter/material.dart'; -import 'package:gradient_app_bar/gradient_app_bar.dart'; -import 'package:flutter_gradients/flutter_gradients.dart'; +import 'package:new_gradient_app_bar/new_gradient_app_bar.dart'; +// TODO: re-add flutter_gradients when it's migrated to null-safe (https://github.com/JonathanMonga/flutter_gradients/issues/9). +// import 'package:flutter_gradients/flutter_gradients.dart'; class GradientExample extends StatelessWidget { - const GradientExample({Key key}) : super(key: key); + const GradientExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final txtStyle = Theme.of(context).textTheme.headline4; return Scaffold( - appBar: GradientAppBar( + appBar: NewGradientAppBar( title: const Text('Gradient appbar'), gradient: const LinearGradient( colors: [Colors.indigo, Colors.cyan], @@ -55,14 +56,14 @@ class GradientExample extends StatelessWidget { child: Text('SweepGradient', style: txtStyle), ), const Divider(), - Container( - height: 300, - decoration: BoxDecoration( - gradient: FlutterGradients.fabledSunset(), - ), - child: Text('Predefined gradient from flutter_gradients', - style: txtStyle), - ) + // Container( + // height: 300, + // decoration: BoxDecoration( + // gradient: FlutterGradients.fabledSunset(), + // ), + // child: Text('Predefined gradient from flutter_gradients', + // style: txtStyle), + // ) ], ), ); diff --git a/lib/routes/widgets_icon_ex.dart b/lib/routes/widgets_icon_ex.dart index 3c41d383..a26f9614 100644 --- a/lib/routes/widgets_icon_ex.dart +++ b/lib/routes/widgets_icon_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class IconExample extends StatelessWidget { - const IconExample({Key key}) : super(key: key); + const IconExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/widgets_image_ex.dart b/lib/routes/widgets_image_ex.dart index 35093cc4..77eaab39 100644 --- a/lib/routes/widgets_image_ex.dart +++ b/lib/routes/widgets_image_ex.dart @@ -5,7 +5,7 @@ import 'package:transparent_image/transparent_image.dart' show kTransparentImage; class ImageExample extends StatelessWidget { - const ImageExample({Key key}) : super(key: key); + const ImageExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/widgets_image_filtered_ex.dart b/lib/routes/widgets_image_filtered_ex.dart index d60723af..865f4d11 100644 --- a/lib/routes/widgets_image_filtered_ex.dart +++ b/lib/routes/widgets_image_filtered_ex.dart @@ -3,7 +3,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; class ImageFilteredExample extends StatefulWidget { - const ImageFilteredExample({Key key}) : super(key: key); + const ImageFilteredExample({Key? key}) : super(key: key); @override _ImageFilteredExampleState createState() => _ImageFilteredExampleState(); diff --git a/lib/routes/widgets_stateful_widgets_ex.dart b/lib/routes/widgets_stateful_widgets_ex.dart index f23011d6..0c170d92 100644 --- a/lib/routes/widgets_stateful_widgets_ex.dart +++ b/lib/routes/widgets_stateful_widgets_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class StatefulWidgetsExample extends StatefulWidget { - const StatefulWidgetsExample({Key key}) : super(key: key); + const StatefulWidgetsExample({Key? key}) : super(key: key); @override State createState() => _StatefulWidgetsExampleState(); @@ -36,8 +36,10 @@ class _StatefulWidgetsExampleState extends State { const Divider(), const Text('Checkbox'), Checkbox( - onChanged: (bool value) { - setState(() => this._checkBoxVal = value); + onChanged: (bool? value) { + if (value != null) { + setState(() => this._checkBoxVal = value); + } }, value: this._checkBoxVal, ), @@ -78,8 +80,10 @@ class _StatefulWidgetsExampleState extends State { .map((int index) => Radio( value: index, groupValue: this._radioVal, - onChanged: (int value) { - setState(() => this._radioVal = value); + onChanged: (int? value) { + if (value != null) { + setState(() => this._radioVal = value); + } }, )) .toList(), diff --git a/lib/routes/widgets_text_ex.dart b/lib/routes/widgets_text_ex.dart index c8222798..9de7bfeb 100644 --- a/lib/routes/widgets_text_ex.dart +++ b/lib/routes/widgets_text_ex.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class TextExample extends StatelessWidget { - const TextExample({Key key}) : super(key: key); + const TextExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/routes/widgets_textfield_ex.dart b/lib/routes/widgets_textfield_ex.dart index 0054952f..bf7256af 100644 --- a/lib/routes/widgets_textfield_ex.dart +++ b/lib/routes/widgets_textfield_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; class TextFieldExample extends StatefulWidget { - const TextFieldExample({Key key}) : super(key: key); + const TextFieldExample({Key? key}) : super(key: key); @override State createState() => _TextFieldExampleState(); diff --git a/lib/routes/widgets_textformfield_ex.dart b/lib/routes/widgets_textformfield_ex.dart index 71560900..08d3567d 100644 --- a/lib/routes/widgets_textformfield_ex.dart +++ b/lib/routes/widgets_textformfield_ex.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class TextFormFieldExample extends StatefulWidget { - const TextFormFieldExample({Key key}) : super(key: key); + const TextFormFieldExample({Key? key}) : super(key: key); @override State createState() => _TextFormFieldExampleState(); @@ -14,15 +14,17 @@ class _TextFormFieldExampleState extends State { final GlobalKey> _passwordFieldKey = GlobalKey>(); - String _name; - String _phoneNumber; - String _email; - String _password; + String? _name; + String? _phoneNumber; + String? _email; + String? _password; - String _validateName(String value) { - if (value.isEmpty) return 'Name is required.'; + String? _validateName(String? value) { + if (value?.isEmpty ?? false) { + return 'Name is required.'; + } final RegExp nameExp = RegExp(r'^[A-Za-z ]+$'); - if (!nameExp.hasMatch(value)) { + if (!nameExp.hasMatch(value!)) { return 'Please enter only alphabetical characters.'; } return null; @@ -47,7 +49,7 @@ class _TextFormFieldExampleState extends State { hintText: 'What do people call you?', labelText: 'Name *', ), - onSaved: (String value) { + onSaved: (String? value) { this._name = value; print('name=$_name'); }, @@ -65,7 +67,7 @@ class _TextFormFieldExampleState extends State { prefixText: '+86', ), keyboardType: TextInputType.phone, - onSaved: (String value) { + onSaved: (String? value) { this._phoneNumber = value; print('phoneNumber=$_phoneNumber'); }, @@ -85,7 +87,7 @@ class _TextFormFieldExampleState extends State { labelText: 'E-mail', ), keyboardType: TextInputType.emailAddress, - onSaved: (String value) { + onSaved: (String? value) { this._email = value; print('email=$_email'); }, @@ -127,7 +129,7 @@ class _TextFormFieldExampleState extends State { const SizedBox(height: 24.0), // "Re-type password" form. TextFormField( - enabled: this._password != null && this._password.isNotEmpty, + enabled: this._password != null && this._password!.isNotEmpty, decoration: const InputDecoration( border: UnderlineInputBorder(), filled: true, @@ -153,13 +155,13 @@ class PasswordField extends StatefulWidget { this.onFieldSubmitted, }); - final Key fieldKey; - final String hintText; - final String labelText; - final String helperText; - final FormFieldSetter onSaved; - final FormFieldValidator validator; - final ValueChanged onFieldSubmitted; + final Key? fieldKey; + final String? hintText; + final String? labelText; + final String? helperText; + final FormFieldSetter? onSaved; + final FormFieldValidator? validator; + final ValueChanged? onFieldSubmitted; @override _PasswordFieldState createState() => _PasswordFieldState(); diff --git a/lib/themes.dart b/lib/themes.dart index 2ea320fa..ba3d766a 100644 --- a/lib/themes.dart +++ b/lib/themes.dart @@ -15,15 +15,12 @@ ThemeData _buildLightTheme() { ); final ThemeData base = ThemeData( brightness: Brightness.light, - accentColorBrightness: Brightness.dark, colorScheme: colorScheme, primaryColor: primaryColor, - buttonColor: primaryColor, indicatorColor: Colors.white, toggleableActiveColor: const Color(0xFF1E88E5), splashColor: Colors.white24, splashFactory: InkRipple.splashFactory, - accentColor: secondaryColor, canvasColor: Colors.white, scaffoldBackgroundColor: Colors.white, backgroundColor: Colors.white, @@ -36,7 +33,6 @@ ThemeData _buildLightTheme() { return base.copyWith( textTheme: base.textTheme, primaryTextTheme: base.primaryTextTheme, - accentTextTheme: base.accentTextTheme, ); } @@ -49,14 +45,11 @@ ThemeData _buildDarkTheme() { ); final ThemeData base = ThemeData( brightness: Brightness.dark, - accentColorBrightness: Brightness.dark, primaryColor: primaryColor, primaryColorDark: const Color(0xFF0050a0), primaryColorLight: secondaryColor, - buttonColor: primaryColor, indicatorColor: Colors.white, toggleableActiveColor: const Color(0xFF6997DF), - accentColor: secondaryColor, canvasColor: const Color(0xFF202124), scaffoldBackgroundColor: const Color(0xFF202124), backgroundColor: const Color(0xFF202124), @@ -69,6 +62,5 @@ ThemeData _buildDarkTheme() { return base.copyWith( textTheme: base.textTheme, primaryTextTheme: base.primaryTextTheme, - accentTextTheme: base.accentTextTheme, ); } diff --git a/pubspec.yaml b/pubspec.yaml index 80892a67..00927887 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,99 +5,98 @@ description: An app showcasing Flutter components, with side-by-side source code version: 2.6.3+74 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.13.0 <3.0.0" publish_to: none dependencies: flutter: sdk: flutter - gradient_app_bar: + # TODO: use canonical package when the nullsafety PR (https://github.com/pedrohff/flutter_heatmap_calendar/pull/11) is in. + # heatmap_calendar: ^1.2.8 + heatmap_calendar: git: - url: https://github.com/TinyProgrammers/GradientAppBar.git - animated_floatactionbuttons: 0.1.0 + url: https://github.com/CouldI/flutter_heatmap_calendar.git + new_gradient_app_bar: + git: + url: https://github.com/GUIKAR741/NewGradientAppBar.git animated_radial_menu: ^0.0.1 animated_text_kit: ^4.2.1 - animations: ^2.0.0 - async: ^2.7.0 - backdrop: ^0.6.1 + animations: ^2.0.1 + async: ^2.8.1 + backdrop: ^0.6.2 badges: ^2.0.1 - cached_network_image: ^2.5.1 - charts_flutter: ^0.10.0 - cloud_firestore: ^0.16.0+1 - cloud_firestore_web: null + cached_network_image: ^3.1.0 + charts_flutter: ^0.11.0 + cloud_firestore: ^2.4.0 + cloud_firestore_web: ^2.3.0 convex_bottom_bar: ^3.0.0 - day_night_switcher: ^0.2.0 + day_night_switcher: ^0.2.0+1 edge_detection: ^1.0.6 - english_words: 3.1.5 - # cf. https://github.com/fluttercandies/extended_image/issues/309 - extended_image: 1.5.0-dev - feature_discovery: ^0.13.0+2 - ffi: ^1.1.1 - firebase_analytics: ^7.0.1 - firebase_analytics_web: null - firebase_auth: ^0.20.1 - firebase_auth_web: null - firebase_core: ^0.7.0 - firebase_core_web: null - firebase_database: ^6.0.0 - firebase_ml_vision: ^0.12.0+2 - firebase_storage: ^7.0.0 - firebase_storage_web: null - fl_chart: ^0.36.1 - flutter_bloc: ^6.1.3 - flutter_gallery_assets: ^0.2.6 - flutter_gradients: ^1.0.0+2 - flutter_markdown: ^0.5.2 + english_words: ^4.0.0 + extended_image: ^4.1.0 + feature_discovery: ^0.14.0 + ffi: ^1.1.2 + firebase_analytics: ^8.2.0 + firebase_analytics_web: ^0.3.0+1 + firebase_auth: ^3.0.1 + firebase_auth_web: ^3.0.0 + firebase_core: ^1.4.0 + firebase_core_web: ^1.1.0 + firebase_database: ^7.1.2 + firebase_storage: ^10.0.1 + firebase_storage_web: ^3.0.0 + fl_chart: ^0.36.3 + flutter_bloc: ^7.1.0 + flutter_gallery_assets: ^1.0.2 + # flutter_gradients: ^1.0.0+2 + flutter_markdown: ^0.6.2 flutter_radar_chart: ^0.2.0 - flutter_riverpod: ^0.12.4 + flutter_riverpod: ^0.14.0+3 flutter_slidable: ^0.6.0 - flutter_state_notifier: ^0.6.1 + flutter_state_notifier: ^0.7.0 flutter_webview_plugin: ^0.4.0 fluttertoast: ^8.0.7 - freezed_annotation: ^0.12.0 - google_fonts: ^1.1.2 - google_sign_in: ^4.5.9 - graphview: ^0.7.0 - heatmap_calendar: ^1.2.8 - hive: 1.4.4+1 - hive_flutter: 0.3.1 - http: 0.12.2 - image: ^2.1.19 - image_picker: ^0.6.7+14 - intl: ^0.16.1 - local_auth: ^0.6.3+4 - lottie: ^0.7.0+1 + freezed_annotation: ^0.14.2 + google_fonts: ^2.1.0 + google_ml_kit: ^0.7.0 + google_sign_in: ^5.0.5 + graphview: ^1.0.0-nullsafety.1 + hive: ^2.0.4 + hive_flutter: ^1.1.0 + http: ^0.13.3 + image: ^3.0.2 + image_picker: ^0.8.2 + intl: ^0.17.0 + local_auth: ^1.1.6 + lottie: ^1.1.0 package_info: ^2.0.2 path: ^1.8.0 - path_provider: ^1.6.28 - photo_view: ^0.11.1 - provider: ^4.3.3 - scoped_model: ^1.1.0 - sembast: ^3.0.3 - shared_preferences: ^0.5.12+4 + path_provider: ^2.0.2 + photo_view: ^0.12.0 + provider: ^5.0.0 + scoped_model: ^2.0.0-nullsafety.0 + sembast: ^3.1.0+2 + shared_preferences: ^2.0.6 shimmer: ^2.0.0 sqflite: ^2.0.0+3 - state_notifier: ^0.6.0 + state_notifier: ^0.7.0 substring_highlight: ^1.0.33 - syntax_highlighter: 0.1.1 + # syntax_highlighter: 0.1.1 transparent_image: ^2.0.0 - tuple: ^1.0.3 - url_launcher: ^5.7.10 - video_player: ^1.0.1 - widget_with_codeview: ^1.0.5 + tuple: ^2.0.0 + url_launcher: ^6.0.9 + video_player: ^2.0.0-nullsafety.9 + widget_with_codeview: ^2.0.0-nullsafe dev_dependencies: - build_runner: ^1.11.5 - flutter_native_splash: ^0.3.2 - freezed: ^0.12.7 - hive_generator: ^0.8.2 + build_runner: ^2.0.6 + flutter_native_splash: ^1.2.0 + freezed: ^0.14.2 + hive_generator: ^1.1.0 + json_serializable: lint: ^1.5.3 -dependency_overrides: - dartx: ^0.5.0 - # path: ^1.6.4 # cf. https://github.com/hivedb/hive/issues/285#issuecomment-633815558 - # Cf. https://pub.dev/packages/flutter_native_splash flutter_native_splash: color: "#f6f6f6"