Version 0.3.0:
+ValueListenableBuilder +valueNotifier property
This commit is contained in:
parent
ddf09936fa
commit
af47014848
|
@ -1,3 +1,9 @@
|
||||||
|
## [0.3.0]
|
||||||
|
|
||||||
|
* Migrated from StreamBuilder to ValueListenableBuilder
|
||||||
|
* 40% improvement in response time (previous 19.2ms, now 11.5ms)
|
||||||
|
* Added valueNotifier property
|
||||||
|
|
||||||
## [0.2.0]
|
## [0.2.0]
|
||||||
|
|
||||||
* Added backgroundColor property
|
* Added backgroundColor property
|
||||||
|
|
|
@ -13,6 +13,7 @@ class Miniplayer extends StatefulWidget {
|
||||||
final Curve curve;
|
final Curve curve;
|
||||||
final double elevation;
|
final double elevation;
|
||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
|
final ValueNotifier<double> valueNotifier;
|
||||||
|
|
||||||
const Miniplayer({
|
const Miniplayer({
|
||||||
Key key,
|
Key key,
|
||||||
|
@ -22,6 +23,7 @@ class Miniplayer extends StatefulWidget {
|
||||||
this.curve = Curves.easeInQuart,
|
this.curve = Curves.easeInQuart,
|
||||||
this.elevation = 0,
|
this.elevation = 0,
|
||||||
this.backgroundColor = const Color(0x70000000),
|
this.backgroundColor = const Color(0x70000000),
|
||||||
|
this.valueNotifier,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -29,6 +31,8 @@ class Miniplayer extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||||
|
ValueNotifier<double> heightNotifier;
|
||||||
|
|
||||||
double _height;
|
double _height;
|
||||||
double _prevHeight;
|
double _prevHeight;
|
||||||
|
|
||||||
|
@ -43,6 +47,11 @@ class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
if (widget.valueNotifier == null)
|
||||||
|
heightNotifier = ValueNotifier(widget.minHeight);
|
||||||
|
else
|
||||||
|
heightNotifier = widget.valueNotifier;
|
||||||
|
|
||||||
_animationController = AnimationController(
|
_animationController = AnimationController(
|
||||||
vsync: this,
|
vsync: this,
|
||||||
duration: Duration(
|
duration: Duration(
|
||||||
|
@ -53,7 +62,7 @@ class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||||
_animationController.addStatusListener((status) {
|
_animationController.addStatusListener((status) {
|
||||||
if (status == AnimationStatus.completed) {
|
if (status == AnimationStatus.completed) {
|
||||||
_animationController.reset();
|
_animationController.reset();
|
||||||
_heightController.add(_endHeight);
|
heightNotifier.value = _endHeight;
|
||||||
_height = _endHeight;
|
_height = _endHeight;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -71,80 +80,76 @@ class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder(
|
return ValueListenableBuilder(
|
||||||
initialData: widget.minHeight,
|
builder: (BuildContext context, double value, Widget child) {
|
||||||
stream: _heightController.stream,
|
var _percentage = ((value - widget.minHeight)) /
|
||||||
builder: (context, AsyncSnapshot<double> snapshot) {
|
(widget.maxHeight - widget.minHeight);
|
||||||
if (snapshot.hasData) {
|
|
||||||
var _percentage = ((snapshot.data - 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: _percentage,
|
opacity: _percentage,
|
||||||
child: Container(color: widget.backgroundColor),
|
child: Container(color: widget.backgroundColor),
|
||||||
),
|
|
||||||
),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
child: SizedBox(
|
|
||||||
height: snapshot.data,
|
|
||||||
child: GestureDetector(
|
|
||||||
child: Material(
|
|
||||||
elevation: widget.elevation,
|
|
||||||
child: Container(
|
|
||||||
constraints: BoxConstraints.expand(),
|
|
||||||
child: widget.builder(snapshot.data, _percentage),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
bool up = _height != widget.maxHeight;
|
|
||||||
animateToHeight(up ? widget.maxHeight : widget.minHeight);
|
|
||||||
},
|
|
||||||
onPanEnd: (details) async {
|
|
||||||
if (_up)
|
|
||||||
animateToHeight(widget.maxHeight);
|
|
||||||
else
|
|
||||||
animateToHeight(widget.minHeight);
|
|
||||||
},
|
|
||||||
onPanUpdate: (details) {
|
|
||||||
_prevHeight = _height;
|
|
||||||
|
|
||||||
//details.delta.dy < 0 -> -- = +
|
|
||||||
var h = _height -= details.delta.dy;
|
|
||||||
|
|
||||||
//Makes sure that height !> maxHeight && !< minHeight
|
|
||||||
if (h > widget.maxHeight) h = widget.maxHeight;
|
|
||||||
if (h < widget.minHeight) h = widget.minHeight;
|
|
||||||
|
|
||||||
//Makes sure that the widget wont rebuild unnecessarily
|
|
||||||
if (_prevHeight == h &&
|
|
||||||
(h == widget.minHeight || h == widget.maxHeight))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_height = h;
|
|
||||||
if (_height == widget.maxHeight)
|
|
||||||
_up = true;
|
|
||||||
else if (_height == widget.minHeight)
|
|
||||||
_up = false;
|
|
||||||
else
|
|
||||||
_up = _prevHeight < _height;
|
|
||||||
|
|
||||||
_heightController.add(h);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
Align(
|
||||||
);
|
alignment: Alignment.bottomCenter,
|
||||||
} else
|
child: SizedBox(
|
||||||
return Container();
|
height: value,
|
||||||
|
child: GestureDetector(
|
||||||
|
child: Material(
|
||||||
|
elevation: widget.elevation,
|
||||||
|
child: Container(
|
||||||
|
constraints: BoxConstraints.expand(),
|
||||||
|
child: widget.builder(value, _percentage),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
bool up = _height != widget.maxHeight;
|
||||||
|
animateToHeight(up ? widget.maxHeight : widget.minHeight);
|
||||||
|
},
|
||||||
|
onPanEnd: (details) async {
|
||||||
|
if (_up)
|
||||||
|
animateToHeight(widget.maxHeight);
|
||||||
|
else
|
||||||
|
animateToHeight(widget.minHeight);
|
||||||
|
},
|
||||||
|
onPanUpdate: (details) {
|
||||||
|
_prevHeight = _height;
|
||||||
|
|
||||||
|
//details.delta.dy < 0 -> -- = +
|
||||||
|
var h = _height -= details.delta.dy;
|
||||||
|
|
||||||
|
//Makes sure that height !> maxHeight && !< minHeight
|
||||||
|
if (h > widget.maxHeight) h = widget.maxHeight;
|
||||||
|
if (h < widget.minHeight) h = widget.minHeight;
|
||||||
|
|
||||||
|
//Makes sure that the widget wont rebuild unnecessarily
|
||||||
|
if (_prevHeight == h &&
|
||||||
|
(h == widget.minHeight || h == widget.maxHeight))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_height = h;
|
||||||
|
if (_height == widget.maxHeight)
|
||||||
|
_up = true;
|
||||||
|
else if (_height == widget.minHeight)
|
||||||
|
_up = false;
|
||||||
|
else
|
||||||
|
_up = _prevHeight < _height;
|
||||||
|
|
||||||
|
heightNotifier.value = h;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
valueListenable: heightNotifier,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +164,7 @@ class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||||
_sizeAnimation.addListener(() {
|
_sizeAnimation.addListener(() {
|
||||||
if (!(_sizeAnimation.value > widget.maxHeight) &&
|
if (!(_sizeAnimation.value > widget.maxHeight) &&
|
||||||
!(_sizeAnimation.value < widget.minHeight))
|
!(_sizeAnimation.value < widget.minHeight))
|
||||||
_heightController.add(_sizeAnimation.value);
|
heightNotifier.value = _sizeAnimation.value;
|
||||||
});
|
});
|
||||||
_animationController.forward();
|
_animationController.forward();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: miniplayer
|
name: miniplayer
|
||||||
description: A lightweight flutter package providing a miniplayer widget which resizes according to drag gestures and returns a builder function with the current height and percentage progress.
|
description: A lightweight flutter package providing a miniplayer widget which resizes according to drag gestures and returns a builder function with the current height and percentage progress.
|
||||||
version: 0.2.0
|
version: 0.3.0
|
||||||
homepage: https://www.peterscode.dev
|
homepage: https://www.peterscode.dev
|
||||||
repository: https://github.com/peterscodee/miniplayer
|
repository: https://github.com/peterscodee/miniplayer
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue