Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.android.tools.build:gradle:3.2.1'
}
}

Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip
100 changes: 58 additions & 42 deletions lib/jumping_dots.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@ class JumpingDotsProgressIndicator extends StatefulWidget {
}

class _JumpingDotsProgressIndicatorState
extends State<JumpingDotsProgressIndicator> with TickerProviderStateMixin {
extends State<JumpingDotsProgressIndicator>
with SingleTickerProviderStateMixin {
int numberOfDots;
int milliseconds;
double fontSize;
double dotSpacing;
Color color;
List<AnimationController> controllers = new List<AnimationController>();
List<Animation<double>> animations = new List<Animation<double>>();
List<Widget> _widgets = new List<Widget>();
AnimationController controller;
List<Animation<double>> animations;
List<Widget> _widgets;

_JumpingDotsProgressIndicatorState({
this.numberOfDots,
Expand All @@ -67,49 +68,64 @@ class _JumpingDotsProgressIndicatorState

initState() {
super.initState();
for (int i = 0; i < numberOfDots; i++) {
_addAnimationControllers();
_buildAnimations(i);
_addListOfDots(i);
}

controllers[0].forward();
}
final totalDuration =
Duration(milliseconds: widget.milliseconds * widget.numberOfDots);
controller = AnimationController(duration: totalDuration, vsync: this);
controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
//restarting animation
controller.reset();
controller.forward();
}
});

void _addAnimationControllers() {
controllers.add(AnimationController(
duration: Duration(milliseconds: milliseconds), vsync: this));
}
// setting up animations for each dot
// how much of the dot animation has to be played before the next dot starts jumping
// 1.0 - each dot jumps after previous has landed
// 0.0 - all dots jumps together
final _jumpDelay = 0.5;
final _animationsInFullJumps = _jumpDelay * widget.numberOfDots + (1.0 - _jumpDelay);
final _jumpDuration = 1.0 / _animationsInFullJumps;
animations = List.generate(widget.numberOfDots,
(index) => _generateDotAnimation(index, _jumpDuration, _jumpDelay));

void _addListOfDots(int index) {
_widgets.add(Padding(
padding: EdgeInsets.only(right: dotSpacing),
child: _JumpingDot(
animation: animations[index],
fontSize: fontSize,
color: color,
),
));
// populate widgets
_widgets = List.generate(widget.numberOfDots, _createDot);

// start animation
controller.forward();
}

void _buildAnimations(int index) {
animations.add(
Tween(begin: widget.beginTweenValue, end: widget.endTweenValue)
.animate(controllers[index])
..addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed)
controllers[index].reverse();
if (index == numberOfDots - 1 &&
status == AnimationStatus.dismissed) {
controllers[0].forward();
}
if (animations[index].value > widget.endTweenValue / 2 &&
index < numberOfDots - 1) {
controllers[index + 1].forward();
}
}));
Animation<double> _generateDotAnimation(
int index, double jumpDuration, double jumpDelay) {
var begin = index * jumpDuration * jumpDelay;
var upAnimation = CurvedAnimation(
parent: controller,
curve: Interval(begin, begin + jumpDuration));

Animation<double> downAnimation = CurvedAnimation(
parent: controller,
curve: Interval(begin, begin + jumpDuration));

downAnimation = Tween(begin: 1.0, end: 0.0).animate(downAnimation);

return Tween<double>(
begin: widget.beginTweenValue,
end: widget.endTweenValue *
2) // to compensate using AnimationMin (max value is 0.5)
.animate(AnimationMin(upAnimation, downAnimation));
}

Widget _createDot(int index) => Padding(
padding: EdgeInsets.only(right: dotSpacing),
child: _JumpingDot(
animation: animations[index],
fontSize: fontSize,
color: color,
),
);

Widget build(BuildContext context) {
return SizedBox(
height: 30.0,
Expand All @@ -121,7 +137,7 @@ class _JumpingDotsProgressIndicatorState
}

dispose() {
for (int i = 0; i < numberOfDots; i++) controllers[i].dispose();
controller.dispose();
super.dispose();
}
}
}
Loading