How do I create an animated number counter?

For anyone still looking, you can use ImplicitlyAnimatedWidget.

Here is an example of an int counter. Works analogously for doubles.

class AnimatedCount extends ImplicitlyAnimatedWidget {
  final int count;

  AnimatedCount({
    Key key,
    @required this.count,
    @required Duration duration,
    Curve curve = Curves.linear
  }) : super(duration: duration, curve: curve, key: key);

  @override
  ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() => _AnimatedCountState();
}

class _AnimatedCountState extends AnimatedWidgetBaseState<AnimatedCount> {
  IntTween _count;

  @override
  Widget build(BuildContext context) {
    return new Text(_count.evaluate(animation).toString());
  }

  @override
  void forEachTween(TweenVisitor visitor) {
    _count = visitor(_count, widget.count, (dynamic value) => new IntTween(begin: value));
  }
}

Just rebuild the widget with a new value and it automatically animates there.


You can simply use this plugin countup: ^0.1.3

  import 'package:countup/countup.dart';

         Countup(
              begin: 100,
              end: 8000,
              duration: Duration(seconds: 3),
              separator: ',',
              style: TextStyle(
                fontSize: 36,
                fontweight : Fontweight.bold,
              ),
            ),

enter image description here


You can use Countup package.

Countup(
  begin: 0,
  end: 7500,
  duration: Duration(seconds: 3),
  separator: ',',
  style: TextStyle(
    fontSize: 36,
  ),
)

https://pub.dev/packages/countup


You should use an AnimationController with an AnimatedBuilder to rebuild your text when the controller changes. Here's an example that increments the miles when the floating action button is pressed (double.toStringAsFixed to get the decimal to show), with a curve on the animation speed:

screenshot

import 'dart:math';
import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(primarySwatch: Colors.purple),
        home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);
  @override
  createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _animation;
  double _miles = 0.0;

  @override initState() {
    _controller = new AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1500),
    );
    _animation = _controller;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    TextTheme textTheme = Theme.of(context).textTheme;
    return new Scaffold(
      body: new Material(
        color: const Color.fromRGBO(246, 251, 8, 1.0),
        child: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              new AnimatedBuilder(
                animation: _animation,
                builder: (BuildContext context, Widget child) {
                  return new Text(
                    _animation.value.toStringAsFixed(1),
                    style: textTheme.display4.copyWith(fontStyle: FontStyle.italic),
                  );
                },
              ),
              new Text(
                  "MILES",
                  style: textTheme.display1.copyWith(fontStyle: FontStyle.italic),
              )
            ],
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.directions_run),
        onPressed: () {
          Random rng = new Random();
          setState(() {
            _miles += rng.nextInt(20) + 0.3;
            _animation = new Tween<double>(
                begin: _animation.value,
                end: _miles,
            ).animate(new CurvedAnimation(
              curve: Curves.fastOutSlowIn,
              parent: _controller,
            ));
          });
          _controller.forward(from: 0.0);
        }
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

Tags:

Dart

Flutter