I have a widget, which contains a subwidget. It get the last and new value in the build method like this:
children: <Widget>[
AspectRatio(
aspectRatio: 1.0,
child: Container(
padding: const EdgeInsets.all(16.0),
child: CircleWidget(_lastWindSpeed/10, _speed/10),
))
],
),
The state will be updatet with
setState
But the widget does not get updated if there are new values.
Did anyone see the issue there?
The class is:
import 'package:flutter/material.dart';
import 'circle_painter.dart';
class CircleWidget extends StatefulWidget {
final double _start;
final double _finish;
CircleWidget(this._start, this._finish);
@override
State<CircleWidget> createState() => new _CircleState();
}
class _CircleState extends State<CircleWidget> with SingleTickerProviderStateMixin{
Animation<double> animation;
double _fraction;
@override
void initState() {
super.initState();
var controller = AnimationController(duration: new Duration(milliseconds: 10), vsync: this);
animation = Tween(begin: widget._start, end: widget._finish).animate(controller)
..addListener((){
setState(() {
_fraction = animation.value;
});
});
controller.forward();
}
@override
Widget build(BuildContext context) {
return new CustomPaint(
painter: new CirclePainter(_fraction));
}
}
Thanks a lot.
If you want your animation to restart when the values of the CircleWidget
change, you need to use the didUpdateWidget
lifecycle. initState
is called only once, while didUpdateWidget
is called every time your the corresponding widget is recreated - note that the values might be the same if a parent widget rebuilt too.
@override
void didUpdateWidget(CircleWidget oldWidget) {
if (oldWidget._start != widget._start ||
oldWidget._end != widget._end) {
// values changed, restart animation.
controller
..reset()
..forward();
}
super.didUpdateWidget(oldWidget);
}
I want to post an alternative solution to the given solution above.
if you want StatefulWidget
to update its underlying data when you call setState
or inside a StreamBuilder
you should pass a UniqueKey
to the StatefulWidget
constructor.
The behavior of fullter when setState
is called is to check if the type did not change in case of StatefulWidget
if not nothing will be updated.
If you add a UniqueKey
to the constuctor, the flutter UI updater will check the key instead.
I hope this helps.
import 'package:flutter/material.dart';
import 'circle_painter.dart';
class CircleWidget extends StatefulWidget {
final double _start;
final double _finish;
CircleWidget(this._start, this._finish, Key:key):super(key:key); // <-- check this
@override
State<CircleWidget> createState() => new _CircleState();
}
class _CircleState extends State<CircleWidget> with SingleTickerProviderStateMixin{
Animation<double> animation;
double _fraction;
@override
void initState() {
super.initState();
var controller = AnimationController(duration: new Duration(milliseconds: 10), vsync: this);
animation = Tween(begin: widget._start, end: widget._finish).animate(controller)
..addListener((){
setState(() {
_fraction = animation.value;
});
});
controller.forward();
}
@override
Widget build(BuildContext context) {
return new CustomPaint(
painter: new CirclePainter(_fraction));
}
}
children: <Widget>[
AspectRatio(
aspectRatio: 1.0,
child: Container(
padding: const EdgeInsets.all(16.0),
child: CircleWidget(_lastWindSpeed/10, _speed/10, key: UniqueKey()), // <---- add UniqueKey as key param here to tell futter to check keys instead of types
))
],
),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With