Initial Open Source release.
This commit is contained in:
parent
071e7a0f98
commit
37cceb644a
|
@ -1,3 +1,3 @@
|
|||
## [0.0.1] - TODO: Add release date.
|
||||
## [0.1.0]
|
||||
|
||||
* TODO: Describe initial release.
|
||||
* Initial Open Source release.
|
||||
|
|
|
@ -1,7 +1,145 @@
|
|||
library miniplayer;
|
||||
|
||||
/// A Calculator.
|
||||
class Calculator {
|
||||
/// Returns [value] plus 1.
|
||||
int addOne(int value) => value + 1;
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef Widget MiniplayerBuilder(double height, double percentage);
|
||||
|
||||
class Miniplayer extends StatefulWidget {
|
||||
final double minHeight;
|
||||
final double maxHeight;
|
||||
final MiniplayerBuilder builder;
|
||||
final Curve curve;
|
||||
|
||||
const Miniplayer(
|
||||
{Key key,
|
||||
@required this.minHeight,
|
||||
@required this.maxHeight,
|
||||
@required this.builder,
|
||||
this.curve = Curves.easeInQuart})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_MiniplayerState createState() => _MiniplayerState();
|
||||
}
|
||||
|
||||
class _MiniplayerState extends State<Miniplayer> with TickerProviderStateMixin {
|
||||
double _height;
|
||||
double _prevHeight;
|
||||
|
||||
//Used to set Size after animation is complete
|
||||
double _endHeight;
|
||||
bool _up;
|
||||
|
||||
StreamController<double> _heightController =
|
||||
StreamController<double>.broadcast();
|
||||
AnimationController _animationController;
|
||||
Animation<double> _sizeAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_animationController = AnimationController(
|
||||
vsync: this,
|
||||
duration: Duration(
|
||||
milliseconds: 300,
|
||||
),
|
||||
);
|
||||
|
||||
_animationController.addStatusListener((status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
_animationController.reset();
|
||||
_heightController.add(_endHeight);
|
||||
_height = _endHeight;
|
||||
}
|
||||
});
|
||||
|
||||
_height = widget.minHeight;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_heightController.close();
|
||||
_animationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder(
|
||||
initialData: widget.minHeight,
|
||||
stream: _heightController.stream,
|
||||
builder: (context, AsyncSnapshot<double> snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var _percentage = ((snapshot.data - widget.minHeight)) /
|
||||
(widget.maxHeight - widget.minHeight);
|
||||
|
||||
return Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
if (_percentage > 0)
|
||||
GestureDetector(
|
||||
onTap: () => animateToHeight(widget.minHeight),
|
||||
child: Container(
|
||||
color: Colors.black.withOpacity(_percentage * 0.5)),
|
||||
),
|
||||
SizedBox(
|
||||
height: snapshot.data,
|
||||
child: GestureDetector(
|
||||
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;
|
||||
var h = _height -=
|
||||
details.delta.dy; //details.delta.dy < 0 -> -- = +
|
||||
|
||||
//Make sure height !> maxHeight && !< minHeight
|
||||
if (h > widget.maxHeight)
|
||||
h = widget.maxHeight;
|
||||
else if (h < widget.minHeight) h = widget.minHeight;
|
||||
|
||||
if (_prevHeight == h &&
|
||||
(h == widget.minHeight || h == widget.maxHeight))
|
||||
return;
|
||||
|
||||
//print('h: ' + h.toString());
|
||||
|
||||
_height = h;
|
||||
_up = _prevHeight < _height;
|
||||
|
||||
_heightController.add(h);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void animateToHeight(final double h) {
|
||||
_endHeight = h;
|
||||
_sizeAnimation = Tween(
|
||||
begin: _height,
|
||||
end: h,
|
||||
).animate(
|
||||
CurvedAnimation(parent: _animationController, curve: widget.curve));
|
||||
|
||||
_sizeAnimation.addListener(() {
|
||||
_heightController.add(_sizeAnimation.value);
|
||||
});
|
||||
_animationController.forward();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
name: miniplayer
|
||||
description: Miniplayer for Flutter
|
||||
version: 0.0.1
|
||||
author:
|
||||
homepage:
|
||||
author: David Peters
|
||||
homepage: peterscode.dev
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
|
@ -12,10 +12,6 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:miniplayer/miniplayer.dart';
|
||||
|
||||
void main() {
|
||||
test('adds one to input values', () {
|
||||
final calculator = Calculator();
|
||||
expect(calculator.addOne(2), 3);
|
||||
expect(calculator.addOne(-7), -6);
|
||||
expect(calculator.addOne(0), 1);
|
||||
expect(() => calculator.addOne(null), throwsNoSuchMethodError);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue