Bruno Antonieto
Bruno Antonieto

Reputation: 109

Flutter slider bar animation

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 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

Answers (2)

Philip Ch'ng
Philip Ch'ng

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

Christopher Moore
Christopher Moore

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

Related Questions