diff --git a/lib/miniplayer.dart b/lib/miniplayer.dart index 409ef5d..ab0359a 100644 --- a/lib/miniplayer.dart +++ b/lib/miniplayer.dart @@ -34,24 +34,24 @@ class Miniplayer extends StatefulWidget { ///Allows you to use a global ValueNotifier with the current progress. ///This can be used to hide the BottomNavigationBar. - final ValueNotifier valueNotifier; + final ValueNotifier? valueNotifier; ///Deprecated @Deprecated( "Migrate onDismiss to onDismissed as onDismiss will be used differently in a future version.") - final Function onDismiss; + final Function? onDismiss; ///If onDismissed is set, the miniplayer can be dismissed - final Function onDismissed; + final Function? onDismissed; //Allows you to manually control the miniplayer in code - final MiniplayerController controller; + final MiniplayerController? controller; const Miniplayer({ - Key key, - @required this.minHeight, - @required this.maxHeight, - @required this.builder, + Key? key, + required this.minHeight, + required this.maxHeight, + required this.builder, this.curve = Curves.easeOut, this.elevation = 0, this.backgroundColor = const Color(0x70000000), @@ -67,17 +67,17 @@ class Miniplayer extends StatefulWidget { } class _MiniplayerState extends State with TickerProviderStateMixin { - ValueNotifier heightNotifier; + late ValueNotifier heightNotifier; ValueNotifier dragDownPercentage = ValueNotifier(0); ///Temporary variable as long as onDismiss is deprecated. Will be removed in a future version. - Function onDismissed; + Function? onDismissed; ///Current y position of drag gesture - double _dragHeight; + late double _dragHeight; ///Used to determine SnapPosition - double _startHeight; + double? _startHeight; bool dismissed = false; @@ -88,19 +88,19 @@ class _MiniplayerState extends State with TickerProviderStateMixin { StreamController _heightController = StreamController.broadcast(); - AnimationController _animationController; + AnimationController? _animationController; void _statusListener(AnimationStatus status) { if (status == AnimationStatus.completed) _resetAnimationController(); } - void _resetAnimationController({Duration duration}) { - if (_animationController != null) _animationController.dispose(); + void _resetAnimationController({Duration? duration}) { + if (_animationController != null) _animationController!.dispose(); _animationController = AnimationController( vsync: this, duration: duration == null ? widget.duration : duration, ); - _animationController.addStatusListener(_statusListener); + _animationController!.addStatusListener(_statusListener); animating = false; } @@ -109,14 +109,14 @@ class _MiniplayerState extends State with TickerProviderStateMixin { if (widget.valueNotifier == null) heightNotifier = ValueNotifier(widget.minHeight); else - heightNotifier = widget.valueNotifier; + heightNotifier = widget.valueNotifier!; _resetAnimationController(); _dragHeight = heightNotifier.value; if (widget.controller != null) - widget.controller.addListener(controllerListener); + widget.controller!.addListener(controllerListener); if (widget.onDismissed != null) onDismissed = widget.onDismissed; @@ -130,10 +130,10 @@ class _MiniplayerState extends State with TickerProviderStateMixin { @override void dispose() { _heightController.close(); - _animationController.dispose(); + _animationController!.dispose(); if (widget.controller != null) - widget.controller.removeListener(controllerListener); + widget.controller!.removeListener(controllerListener); super.dispose(); } @@ -143,9 +143,9 @@ class _MiniplayerState extends State with TickerProviderStateMixin { if (dismissed) return Container(); return ValueListenableBuilder( - builder: (BuildContext context, double value, Widget child) { - var _percentage = ((value - widget.minHeight)) / - (widget.maxHeight - widget.minHeight); + builder: (BuildContext context, double? value, Widget? child) { + var _percentage = + (value! - widget.minHeight) / (widget.maxHeight - widget.minHeight); return Stack( alignment: Alignment.bottomCenter, @@ -166,12 +166,14 @@ class _MiniplayerState extends State with TickerProviderStateMixin { child: GestureDetector( child: ValueListenableBuilder( valueListenable: dragDownPercentage, - builder: (context, value, child) { - if (value == 0) return child; + builder: (context, dynamic value, child) { + if (value == 0) return child!; return Opacity( opacity: borderDouble( - minRange: 0, maxRange: 1, value: 1 - value * 0.8), + minRange: 0, + maxRange: 1, + value: 1 - value * 0.8 as double), child: Transform.translate( offset: Offset(0.0, widget.minHeight * value * 0.5), child: child, @@ -206,12 +208,12 @@ class _MiniplayerState extends State with TickerProviderStateMixin { }, onPanEnd: (details) async { ///Calculates drag speed - double speed = - (_dragHeight - _startHeight * _dragHeight < _startHeight - ? 1 - : -1) / - updateCount * - 100; + double speed = (_dragHeight - _startHeight! * _dragHeight < + _startHeight! + ? 1 + : -1) / + updateCount * + 100; ///Define the percentage distance depending on the speed with which the widget should snap double snapPercentage = 0.005; @@ -230,7 +232,7 @@ class _MiniplayerState extends State with TickerProviderStateMixin { value: _dragHeight); ///Started from expanded state - if (_startHeight > widget.minHeight) { + if (_startHeight! > widget.minHeight) { if (_percentageMax > 1 - snapPercentage) snap = PanelState.MAX; } @@ -294,7 +296,7 @@ class _MiniplayerState extends State with TickerProviderStateMixin { dragDownPercentage.value = percentageDown; if (percentageDown >= 1 && animation && !dismissed) { - if (onDismissed != null) onDismissed(); + if (onDismissed != null) onDismissed!(); setState(() { dismissed = true; }); @@ -318,7 +320,7 @@ class _MiniplayerState extends State with TickerProviderStateMixin { } ///Animates the panel height to a specific value - void _animateToHeight(final double h, {Duration duration}) { + void _animateToHeight(final double h, {Duration? duration}) { final startHeight = _dragHeight; if (duration != null) _resetAnimationController(duration: duration); @@ -327,7 +329,7 @@ class _MiniplayerState extends State with TickerProviderStateMixin { begin: startHeight, end: h, ).animate( - CurvedAnimation(parent: _animationController, curve: widget.curve)); + CurvedAnimation(parent: _animationController!, curve: widget.curve)); _sizeAnimation.addListener(() { if (_sizeAnimation.value == startHeight) return; @@ -338,34 +340,35 @@ class _MiniplayerState extends State with TickerProviderStateMixin { }); animating = true; - _animationController.forward(from: 0); + _animationController!.forward(from: 0); } - //Listener function for the controller + ///Listener function for the controller + ///Controller is always non-null as listener is only added after a null check void controllerListener() { - switch (widget.controller.value.height) { + switch (widget.controller!.value!.height) { case -1: _animateToHeight( widget.minHeight, - duration: widget.controller.value.duration, + duration: widget.controller!.value!.duration, ); break; case -2: _animateToHeight( widget.maxHeight, - duration: widget.controller.value.duration, + duration: widget.controller!.value!.duration, ); break; case -3: _animateToHeight( 0, - duration: widget.controller.value.duration, + duration: widget.controller!.value!.duration, ); break; default: _animateToHeight( - widget.controller.value.height.toDouble(), - duration: widget.controller.value.duration, + widget.controller!.value!.height.toDouble(), + duration: widget.controller!.value!.duration, ); break; } @@ -378,29 +381,30 @@ enum PanelState { MAX, MIN, DISMISS } //ControllerData class. Used for the controller class ControllerData { final int height; - final Duration duration; + final Duration? duration; const ControllerData(this.height, this.duration); } //MiniplayerController class -class MiniplayerController extends ValueNotifier { +class MiniplayerController extends ValueNotifier { MiniplayerController() : super(null); //Animates to a given height or state(expanded, dismissed, ...) - void animateToHeight({double height, PanelState state, Duration duration}) { + void animateToHeight( + {double? height, PanelState? state, Duration? duration}) { if (height == null && state == null) throw ("Miniplayer: One of the two parameters, height or status, is required."); if (height != null && state != null) throw ("Miniplayer: Only one of the two parameters, height or status, can be specified."); - ControllerData valBefore = value; + ControllerData? valBefore = value; if (state != null) value = ControllerData(state.heightCode, duration); else { - if (height < 0) return; + if (height! < 0) return; value = ControllerData(height.round(), duration); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 28134a2..276496e 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -16,11 +16,16 @@ extension SelectedColorExtension on PanelState { } ///Calculates the percentage of a value within a given range of values -double percentageFromValueInRange({final double min, max, value}) { +double percentageFromValueInRange( + {required double min, required max, required value}) { return (value - min) / (max - min); } -double borderDouble({double minRange, double maxRange, double value}) { +double borderDouble({ + required double minRange, + required double maxRange, + required double value, +}) { if (value > maxRange) return maxRange; if (value < minRange) return minRange; return value; diff --git a/pubspec.yaml b/pubspec.yaml index f6f0ec3..f5c9ee1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://www.peterscode.dev repository: https://github.com/peterscodee/miniplayer environment: - sdk: ">=2.6.0 <3.0.0" + sdk: '>=2.12.0-0 <3.0.0' flutter: ">=1.0.0 <2.0.0" dependencies: