Reputation: 109
I wrote this code that is basically a slide bar with a fixed value between 0 and 100. When I press the shuffle button its value (jovirometro.toDouble
variable) changes. All I wish to make is an animation that slides from a value to other. The user doesn't interact with the slider.
Here's how it looks now
child: Container(
height: 10,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 0.1),
gradient: LinearGradient(
colors: [
Colors.red,
Colors.redAccent,
Colors.white,
Colors.lightGreenAccent,
Colors.green
]
),
borderRadius: BorderRadius.circular(10),
),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.white,
inactiveTrackColor: Colors.white,
trackHeight: 0.1,
thumbColor: Colors.white,
thumbShape: CustomSliderThumbShape(enabledThumbRadius: 10),
overlayColor: Colors.white.withAlpha(1),
),
child: Slider(
min: 0,
max: 100,
value: jovirometro.toDouble(),
onChanged: (value){setState((){});},
),
),
),
The jovirometro's variable is
var jovirometro = snapshot.data.documents[_word]['jovirometro'];
from the Firestore server, and the shuffle button changes the "_word" parameter.
Upvotes: 0
Views: 4085
Reputation: 671
I was having the same issue and managed to solved mine with AnimatedBuilder
.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 10,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 0.1),
gradient: LinearGradient(colors: [
Colors.red,
Colors.redAccent,
Colors.white,
Colors.lightGreenAccent,
Colors.green
]),
borderRadius: BorderRadius.circular(10),
),
child: AnimatedBuilder(
animation: _animationController,
builder: (_, __) {
return SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.white,
inactiveTrackColor: Colors.white,
trackHeight: 0.1,
thumbColor: Colors.white,
overlayColor: Colors.white.withAlpha(1),
),
child: Slider(
value: _animationController.value,
onChanged: null,
),
);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_animationController.animateTo(Random().nextDouble());
},
child: Icon(Icons.autorenew),
),
);
}
}
I've created a codepen based on your code and my solution to it.
https://codepen.io/pczn0327/pen/XWXYKap
Upvotes: 1
Reputation: 17113
Before asking here on SO you should do some research to try to solve the problem yourself. Flutter provides excellent documentation in my opinion and even has an Animations tutorial that would have been of great help to you.
For your case you should use an AnimationController
.
You need to add with SingleTickerProviderStateMixin
to your State
of your StatefulWidget
, instantiate the controller in initState
, and add a listener to call setState
on value changes:
_controller = AnimationController(
vsync: this,
duration: widget.duration,
upperBound: 100.0,
);
..addListener(() {
setState(() {
});
and dispose
it in dispose
:
_controller.dispose();
You can use _controller.value
to get the current value of your animation, which should be passed to the Slider
:
child: Slider(
min: 0,
max: 100,
value: _controller.value,
onChanged: (value){setState((){});},
),
Now whenever you want to animate the value of the slider call animateTo
, or one of the many methods of animating with the AnimationController
, setting the target
as your intended value, and optionally setting the Duration
and Curve
of the animation.
Upvotes: 2