From 44b7515c20c27551ea933062e47e80af13a21886 Mon Sep 17 00:00:00 2001 From: Igor Czapski Date: Wed, 2 Jun 2021 19:02:55 +0200 Subject: [PATCH] Migrate package to null safety --- example/lib/main.dart | 18 +++++---- example/pubspec.lock | 87 ++++++++++++++++++++----------------------- example/pubspec.yaml | 2 +- lib/snappable.dart | 69 +++++++++++++++++++++------------- pubspec.lock | 87 ++++++++++++++++++++----------------------- pubspec.yaml | 4 +- 6 files changed, 136 insertions(+), 131 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 59708f0..c8e368e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -43,22 +43,24 @@ class _MyHomePageState extends State { color: Colors.deepPurple, alignment: Alignment.center, child: Text( - 'This will be sanpped', - style: Theme.of(context).textTheme.title.copyWith( + 'This will be snapped', + style: Theme.of(context).textTheme.headline6?.copyWith( color: Colors.white, ), ), ), ), ), - RaisedButton( + ElevatedButton( child: Text('Snap / Reverse'), onPressed: () { - SnappableState state = _snappableKey.currentState; - if (state.isGone) { - state.reset(); - } else { - state.snap(); + SnappableState? state = _snappableKey.currentState; + if (state != null) { + if (state.isGone) { + state.reset(); + } else { + state.snap(); + } } }, ) diff --git a/example/pubspec.lock b/example/pubspec.lock index 8e2a701..d17019b 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,56 +7,56 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.10" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" + version: "3.1.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.6.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" - collection: + version: "1.2.0" + clock: dependency: transitive description: - name: collection + name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" - convert: + version: "1.1.0" + collection: dependency: transitive description: - name: convert + name: collection url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "1.15.0" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.1+1" + version: "3.0.1" cupertino_icons: dependency: "direct main" description: @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -80,49 +87,35 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "3.0.2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.5" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" + version: "1.8.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" + version: "4.1.0" sky_engine: dependency: transitive description: flutter @@ -141,62 +134,62 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.5" + version: "0.3.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "5.1.1" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1f759e9..cd006d4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,7 +14,7 @@ description: A new Flutter project. version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: diff --git a/lib/snappable.dart b/lib/snappable.dart index cd4d8f5..21dc7c9 100644 --- a/lib/snappable.dart +++ b/lib/snappable.dart @@ -35,11 +35,11 @@ class Snappable extends StatefulWidget { final bool snapOnTap; /// Function that gets called when snap ends - final VoidCallback onSnapped; + final VoidCallback? onSnapped; const Snappable({ - Key key, - @required this.child, + Key? key, + required this.child, this.offset = const Offset(64, -32), this.duration = const Duration(milliseconds: 5000), this.randomDislocationOffset = const Offset(64, 32), @@ -61,19 +61,19 @@ class SnappableState extends State bool get isGone => _animationController.isCompleted; /// Main snap effect controller - AnimationController _animationController; + late AnimationController _animationController; /// Key to get image of a [widget.child] GlobalKey _globalKey = GlobalKey(); /// Layers of image - List _layers; + List? _layers; /// Values from -1 to 1 to dislocate the layers a bit - List _randoms; + late List _randoms; /// Size of child widget - Size size; + Size? size; @override void initState() { @@ -85,9 +85,10 @@ class SnappableState extends State if (widget.onSnapped != null) { _animationController.addStatusListener((status) { - if (status == AnimationStatus.completed) widget.onSnapped(); + if (status == AnimationStatus.completed) widget.onSnapped!(); }); } + _prepareRandoms(); } @override @@ -102,11 +103,13 @@ class SnappableState extends State onTap: widget.snapOnTap ? () => isGone ? reset() : snap() : null, child: Stack( children: [ - if (_layers != null) ..._layers.map(_imageToWidget), + ..._generateWidgetsFromImages(), AnimatedBuilder( animation: _animationController, - builder: (context, child) { - return _animationController.isDismissed ? child : Container(); + builder: (_, Widget? child) { + return _animationController.isDismissed + ? child! + : const SizedBox.shrink(); }, child: RepaintBoundary( key: _globalKey, @@ -122,6 +125,7 @@ class SnappableState extends State Future snap() async { //get image from child final fullImage = await _getImageFromWidget(); + if (fullImage == null) return; //create an image for every bucket List _images = List.generate( @@ -156,13 +160,8 @@ class SnappableState extends State _layers = await compute, List>( _encodeImages, _images); - //prepare random dislocations and set state - setState(() { - _randoms = List.generate( - widget.numberOfBuckets, - (i) => (math.Random().nextDouble() - 0.5) * 2, - ); - }); + _prepareRandoms(); + setState(() {}); //give a short delay to draw images await Future.delayed(Duration(milliseconds: 100)); @@ -179,12 +178,19 @@ class SnappableState extends State }); } + Iterable _generateWidgetsFromImages() { + if (_layers == null) return []; + return _layers!.map(_imageToWidget); + } + Widget _imageToWidget(Uint8List layer) { //get layer's index in the list - int index = _layers.indexOf(layer); + //This is invoked in build() and _layers aren't null here. + int index = _layers!.indexOf(layer); //based on index, calculate when this layer should start and end - double animationStart = (index / _layers.length) * _lastLayerAnimationStart; + double animationStart = + (index / _layers!.length) * _lastLayerAnimationStart; double animationEnd = animationStart + _singleLayerAnimationLength; //create interval animation using only part of whole animation @@ -237,20 +243,31 @@ class SnappableState extends State } /// Gets an Image from a [child] and caches [size] for later us - Future _getImageFromWidget() async { - RenderRepaintBoundary boundary = - _globalKey.currentContext.findRenderObject(); + Future _getImageFromWidget() async { + RenderObject? rObj = _globalKey.currentContext?.findRenderObject(); + RenderRepaintBoundary? boundary = rObj as RenderRepaintBoundary?; //cache image for later - size = boundary.size; + size = boundary?.size; + if (boundary == null) return null; + var img = await boundary.toImage(); - var byteData = await img.toByteData(format: ImageByteFormat.png); - var pngBytes = byteData.buffer.asUint8List(); + ByteData? byteData = await img.toByteData(format: ImageByteFormat.png); + var pngBytes = byteData?.buffer.asUint8List(); + if (pngBytes == null) return null; return image.decodeImage(pngBytes); } int _gauss(double center, double value) => (1000 * math.exp(-(math.pow((value - center), 2) / 0.14))).round(); + + /// Prepare random dislocations and set state + void _prepareRandoms() { + _randoms = List.generate( + widget.numberOfBuckets, + (i) => (math.Random().nextDouble() - 0.5) * 2, + ); + } } /// This is slow! Run it in separate isolate diff --git a/pubspec.lock b/pubspec.lock index 7ad6fd5..88ce165 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,56 +7,63 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.10" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" + version: "3.1.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.6.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" - collection: + version: "1.2.0" + clock: dependency: transitive description: - name: collection + name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" - convert: + version: "1.1.0" + collection: dependency: transitive description: - name: convert + name: collection url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "1.15.0" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "3.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -73,49 +80,35 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "3.0.2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.5" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" + version: "1.8.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" + version: "4.1.0" sky_engine: dependency: transitive description: flutter @@ -127,62 +120,62 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.5" + version: "0.3.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" xml: dependency: transitive description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "5.1.1" sdks: - dart: ">=2.4.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index fdce027..2e102fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,12 +5,12 @@ author: Marcin SzaƂek homepage: https://github.com/MarcinusX/snappable environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter - image: ^2.1.4 + image: ^3.0.2 dev_dependencies: flutter_test: