Added WillPopScope

This commit is contained in:
David 2020-12-15 13:14:16 +01:00
parent d99551203d
commit 6918f18f8a
1 changed files with 126 additions and 117 deletions

View File

@ -142,132 +142,141 @@ class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (dismissed) return Container(); if (dismissed) return Container();
return ValueListenableBuilder( return WillPopScope(
builder: (BuildContext context, double value, Widget child) { onWillPop: () async {
var _percentage = ((value - widget.minHeight)) / if (heightNotifier.value > widget.minHeight) {
(widget.maxHeight - widget.minHeight); _snapToPosition(PanelState.MIN);
return false;
}
return true;
},
child: ValueListenableBuilder(
builder: (BuildContext context, double value, Widget child) {
var _percentage = ((value - widget.minHeight)) /
(widget.maxHeight - widget.minHeight);
return Stack( return Stack(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
children: [ children: [
if (_percentage > 0) if (_percentage > 0)
GestureDetector( GestureDetector(
onTap: () => _animateToHeight(widget.minHeight), onTap: () => _animateToHeight(widget.minHeight),
child: Opacity( child: Opacity(
opacity: borderDouble( opacity: borderDouble(
minRange: 0, maxRange: 1, value: _percentage), minRange: 0, maxRange: 1, value: _percentage),
child: Container(color: widget.backgroundColor), child: Container(color: widget.backgroundColor),
),
), ),
), Align(
Align( alignment: Alignment.bottomCenter,
alignment: Alignment.bottomCenter, child: SizedBox(
child: SizedBox( height: value,
height: value, child: GestureDetector(
child: GestureDetector( child: ValueListenableBuilder(
child: ValueListenableBuilder( valueListenable: dragDownPercentage,
valueListenable: dragDownPercentage, builder: (context, value, child) {
builder: (context, value, child) { if (value == 0) return child;
if (value == 0) return child;
return Opacity( return Opacity(
opacity: borderDouble( opacity: borderDouble(
minRange: 0, maxRange: 1, value: 1 - value * 0.8), minRange: 0, maxRange: 1, value: 1 - value * 0.8),
child: Transform.translate( child: Transform.translate(
offset: Offset(0.0, widget.minHeight * value * 0.5), offset: Offset(0.0, widget.minHeight * value * 0.5),
child: child, child: child,
), ),
); );
}, },
child: Material( child: Material(
color: Theme.of(context).canvasColor, color: Theme.of(context).canvasColor,
child: Container( child: Container(
constraints: BoxConstraints.expand(), constraints: BoxConstraints.expand(),
child: widget.builder(value, _percentage), child: widget.builder(value, _percentage),
decoration: BoxDecoration( decoration: BoxDecoration(
boxShadow: <BoxShadow>[ boxShadow: <BoxShadow>[
BoxShadow( BoxShadow(
color: Colors.black45, color: Colors.black45,
blurRadius: widget.elevation, blurRadius: widget.elevation,
offset: Offset(0.0, 4)) offset: Offset(0.0, 4))
], ],
color: Colors.white, color: Colors.white,
),
), ),
), ),
), ),
onTap: () => _snapToPosition(_dragHeight != widget.maxHeight
? PanelState.MAX
: PanelState.MIN),
onPanStart: (details) {
_startHeight = _dragHeight;
updateCount = 0;
if (animating) _resetAnimationController();
},
onPanEnd: (details) async {
///Calculates drag speed
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;
if (speed <= 4)
snapPercentage = 0.2;
else if (speed <= 9)
snapPercentage = 0.08;
else if (speed <= 50) snapPercentage = 0.01;
///Determine to which SnapPosition the widget should snap
PanelState snap = PanelState.MIN;
final _percentageMax = percentageFromValueInRange(
min: widget.minHeight,
max: widget.maxHeight,
value: _dragHeight);
///Started from expanded state
if (_startHeight > widget.minHeight) {
if (_percentageMax > 1 - snapPercentage)
snap = PanelState.MAX;
}
///Started from minified state
else {
if (_percentageMax > snapPercentage)
snap = PanelState.MAX;
else
///DismissedPercentage > 0.2 -> dismiss
if (onDismissed != null &&
percentageFromValueInRange(
min: widget.minHeight,
max: 0,
value: _dragHeight) >
snapPercentage) snap = PanelState.DISMISS;
}
///Snap to position
_snapToPosition(snap);
},
onPanUpdate: (details) {
if (dismissed) return;
_dragHeight -= details.delta.dy;
updateCount++;
_handleHeightChange();
},
), ),
onTap: () => _snapToPosition(_dragHeight != widget.maxHeight
? PanelState.MAX
: PanelState.MIN),
onPanStart: (details) {
_startHeight = _dragHeight;
updateCount = 0;
if (animating) _resetAnimationController();
},
onPanEnd: (details) async {
///Calculates drag speed
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;
if (speed <= 4)
snapPercentage = 0.2;
else if (speed <= 9)
snapPercentage = 0.08;
else if (speed <= 50) snapPercentage = 0.01;
///Determine to which SnapPosition the widget should snap
PanelState snap = PanelState.MIN;
final _percentageMax = percentageFromValueInRange(
min: widget.minHeight,
max: widget.maxHeight,
value: _dragHeight);
///Started from expanded state
if (_startHeight > widget.minHeight) {
if (_percentageMax > 1 - snapPercentage)
snap = PanelState.MAX;
}
///Started from minified state
else {
if (_percentageMax > snapPercentage)
snap = PanelState.MAX;
else
///DismissedPercentage > 0.2 -> dismiss
if (onDismissed != null &&
percentageFromValueInRange(
min: widget.minHeight,
max: 0,
value: _dragHeight) >
snapPercentage) snap = PanelState.DISMISS;
}
///Snap to position
_snapToPosition(snap);
},
onPanUpdate: (details) {
if (dismissed) return;
_dragHeight -= details.delta.dy;
updateCount++;
_handleHeightChange();
},
), ),
), ),
), ],
], );
); },
}, valueListenable: heightNotifier,
valueListenable: heightNotifier, ),
); );
} }