From 6ce676339a76beb70e178f5df7fb6c60744943b0 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Mon, 14 Dec 2020 23:59:09 -0800 Subject: [PATCH 1/3] Added tap count to expose setState bug. --- example/lib/main.dart | 260 +++++++++++++++++++++--------------------- 1 file changed, 128 insertions(+), 132 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 21bbaa5..ff3e9d1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -47,122 +47,111 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - final _textAnimationKit = [ - ListView( - scrollDirection: Axis.horizontal, - children: [ - Row( - mainAxisSize: MainAxisSize.min, + List get _textAnimationKit => [ + ListView( + scrollDirection: Axis.horizontal, children: [ - SizedBox( - width: 20.0, - height: 100.0, - ), - Text( - 'Be', - style: TextStyle(fontSize: 43.0), - ), - SizedBox( - width: 20.0, - height: 100.0, - ), - RotateAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - isRepeatingAnimation: true, - totalRepeatCount: 10, - text: ['AWESOME', 'OPTIMISTIC', 'DIFFERENT'], - // alignment: Alignment(1.0, 0.5), - textStyle: TextStyle(fontSize: 40.0, fontFamily: 'Horizon'), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + width: 20.0, + height: 100.0, + ), + Text( + 'Be', + style: TextStyle(fontSize: 43.0), + ), + SizedBox( + width: 20.0, + height: 100.0, + ), + RotateAnimatedTextKit( + onTap: () => _onTap(), + isRepeatingAnimation: true, + totalRepeatCount: 10, + text: ['AWESOME', 'OPTIMISTIC', 'DIFFERENT'], + // alignment: Alignment(1.0, 0.5), + textStyle: TextStyle(fontSize: 40.0, fontFamily: 'Horizon'), + ), + ], ), ], ), - ], - ), - FadeAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - text: ['do IT!', 'do it RIGHT!!', 'do it RIGHT NOW!!!'], - textStyle: TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold), - ), - SizedBox( - width: 250.0, - child: TyperAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - text: [ - 'It is not enough to do your best,', - 'you must know what to do,', - 'and then do your best', - '- W.Edwards Deming', - ], - textStyle: TextStyle(fontSize: 30.0, fontFamily: 'Bobbers'), - ), - ), - SizedBox( - width: 250.0, - child: TypewriterAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - text: [ - 'Discipline is the best tool', - 'Design first, then code', - 'Do not patch bugs out, rewrite them', - 'Do not test bugs out, design them out', - ], - textStyle: TextStyle(fontSize: 30.0, fontFamily: 'Agne'), - ), - ), - ScaleAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - text: ['Think', 'Build', 'Ship'], - textStyle: TextStyle(fontSize: 70.0, fontFamily: 'Canterbury'), - ), + FadeAnimatedTextKit( + onTap: () => _onTap(), + text: ['do IT!', 'do it RIGHT!!', 'do it RIGHT NOW!!!'], + textStyle: TextStyle(fontSize: 32.0, fontWeight: FontWeight.bold), + ), + SizedBox( + width: 250.0, + child: TyperAnimatedTextKit( + onTap: () => _onTap(), + text: [ + 'It is not enough to do your best,', + 'you must know what to do,', + 'and then do your best', + '- W.Edwards Deming', + ], + textStyle: TextStyle(fontSize: 30.0, fontFamily: 'Bobbers'), + ), + ), + SizedBox( + width: 250.0, + child: TypewriterAnimatedTextKit( + onTap: () => _onTap(), + text: [ + 'Discipline is the best tool', + 'Design first, then code', + 'Do not patch bugs out, rewrite them', + 'Do not test bugs out, design them out', + ], + textStyle: TextStyle(fontSize: 30.0, fontFamily: 'Agne'), + ), + ), + ScaleAnimatedTextKit( + onTap: () => _onTap(), + text: ['Think', 'Build', 'Ship'], + textStyle: TextStyle(fontSize: 70.0, fontFamily: 'Canterbury'), + ), - /// colors.length >= 2 - ColorizeAnimatedTextKit( - onTap: () { - print('Tap Event'); - }, - text: [ - 'Larry Page', - 'Bill Gates', - 'Steve Jobs', - ], - textStyle: TextStyle(fontSize: 50.0, fontFamily: 'Horizon'), - colors: [ - Colors.purple, - Colors.blue, - Colors.yellow, - Colors.red, - ], - ), + /// colors.length >= 2 + ColorizeAnimatedTextKit( + onTap: () => _onTap(), + text: [ + 'Larry Page', + 'Bill Gates', + 'Steve Jobs', + ], + textStyle: TextStyle(fontSize: 50.0, fontFamily: 'Horizon'), + colors: [ + Colors.purple, + Colors.blue, + Colors.yellow, + Colors.red, + ], + ), - Center( - child: TextLiquidFill( - text: 'LIQUIDY', - waveColor: Colors.blueAccent, - boxBackgroundColor: Colors.redAccent, - textStyle: TextStyle(fontSize: 80, fontWeight: FontWeight.bold), - boxHeight: 300, - ), - ), + Center( + child: TextLiquidFill( + text: 'LIQUIDY', + waveColor: Colors.blueAccent, + boxBackgroundColor: Colors.redAccent, + textStyle: TextStyle(fontSize: 80, fontWeight: FontWeight.bold), + boxHeight: 300, + ), + ), - WavyAnimatedTextKit( - textStyle: TextStyle(fontSize: 20), - text: [ - 'Hello World', - 'Look at the waves', - 'They look so Amazing', - ], - ), - ]; + WavyAnimatedTextKit( + onTap: () => _onTap(), + textStyle: TextStyle(fontSize: 20), + text: [ + 'Hello World', + 'Look at the waves', + 'They look so Amazing', + ], + ), + ]; final _colors = [ Colors.orange[800], @@ -176,20 +165,26 @@ class _MyHomePageState extends State { ]; int _index = 0; + int _tapCount = 0; + + void _onTap() { + print('Tap Event'); + setState(() { + _tapCount++; + }); + } @override Widget build(BuildContext context) { return Scaffold( + appBar: AppBar( + title: Text( + labels[_index], + style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), + ), + ), body: Column( children: [ - SizedBox( - height: 40.0, - width: double.maxFinite, - ), - Text( - labels[_index], - style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), - ), Expanded( child: Container(), ), @@ -200,25 +195,26 @@ class _MyHomePageState extends State { width: 300.0, ), Expanded( - child: Container(), - ), - InkWell( - child: Icon( - Icons.play_circle_filled, - size: 70.0, + child: Container( + alignment: Alignment.center, + child: Text('Taps: $_tapCount'), ), - onTap: () { - setState(() { - _index = ++_index % _textAnimationKit.length; - }); - }, - ), - SizedBox( - height: 20.0, - width: double.maxFinite, ), ], ), + floatingActionButton: FloatingActionButton( + onPressed: () { + setState(() { + _index = ++_index % _textAnimationKit.length; + _tapCount = 0; + }); + }, + tooltip: 'Increment', + child: const Icon( + Icons.play_circle_filled, + size: 50.0, + ), + ), ); } } From 3b00e2807c00af58d86595e562bec55137fe15f6 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Tue, 15 Dec 2020 00:00:24 -0800 Subject: [PATCH 2/3] Fixed the bug where a setState rebuild would lose the animation state information. --- lib/src/animated_text.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/src/animated_text.dart b/lib/src/animated_text.dart index eeca86e..b58bed9 100644 --- a/lib/src/animated_text.dart +++ b/lib/src/animated_text.dart @@ -148,6 +148,8 @@ class _AnimatedTextKitState extends State with TickerProviderStateMixin { AnimationController _controller; + AnimatedText _currentAnimatedText; + int _currentRepeatCount = 0; int _index = 0; @@ -171,8 +173,7 @@ class _AnimatedTextKitState extends State @override Widget build(BuildContext context) { - final animatedText = widget.animatedTexts[_index]; - final completeText = animatedText.completeText(); + final completeText = _currentAnimatedText.completeText(); return GestureDetector( behavior: HitTestBehavior.opaque, onTap: _onTap, @@ -181,8 +182,7 @@ class _AnimatedTextKitState extends State : AnimatedBuilder( animation: _controller, child: completeText, - builder: (BuildContext context, Widget child) => - animatedText.animatedBuilder(context, child), + builder: _currentAnimatedText.animatedBuilder, ), ); } @@ -222,14 +222,14 @@ class _AnimatedTextKitState extends State } void _initAnimation() { - final animatedText = widget.animatedTexts[_index]; + _currentAnimatedText = widget.animatedTexts[_index]; _controller = AnimationController( - duration: animatedText.duration, + duration: _currentAnimatedText.duration, vsync: this, ); - animatedText.initAnimation(_controller); + _currentAnimatedText.initAnimation(_controller); _controller.addStatusListener(_animationEndCallback); @@ -262,9 +262,9 @@ class _AnimatedTextKitState extends State _nextAnimation(); } } else { - final animatedText = widget.animatedTexts[_index]; final left = - (animatedText.remaining ?? animatedText.duration).inMilliseconds; + (_currentAnimatedText.remaining ?? _currentAnimatedText.duration) + .inMilliseconds; _controller.stop(); From 835c0db564572bde2059319054361817aba37860 Mon Sep 17 00:00:00 2001 From: Anthony Whitford Date: Tue, 15 Dec 2020 00:30:33 -0800 Subject: [PATCH 3/3] Added missing parameter type to _animationEndCallback. --- lib/src/animated_text.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/animated_text.dart b/lib/src/animated_text.dart index b58bed9..466437e 100644 --- a/lib/src/animated_text.dart +++ b/lib/src/animated_text.dart @@ -231,9 +231,9 @@ class _AnimatedTextKitState extends State _currentAnimatedText.initAnimation(_controller); - _controller.addStatusListener(_animationEndCallback); - - _controller.forward(); + _controller + ..addStatusListener(_animationEndCallback) + ..forward(); } void _setPause() { @@ -246,7 +246,7 @@ class _AnimatedTextKitState extends State widget.onNextBeforePause?.call(_index, isLast); } - void _animationEndCallback(state) { + void _animationEndCallback(AnimationStatus state) { if (state == AnimationStatus.completed) { _setPause(); assert(null == _timer || !_timer.isActive);