Added WillPopScope
This commit is contained in:
parent
d99551203d
commit
6918f18f8a
|
@ -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,
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue