如何创建动画数字计数器?

How do I create an animated number counter?

我想创建一个从起始值到结束值的动画数字计数器。我研究过使用计时器,但似乎无法 animate/update 正确说明。包括十进制值会很好,但一个简单的整数动画就可以了。

Number counter that needs to animate

double _mileCounter = 643.6;

_animateMileCounter() {
  Duration duration = new Duration(milliseconds: 300);
  return new Timer(duration, _updateMileCounter);
}

_updateMileCounter() {
  setState(() {
    _mileCounter += 1;
  });
}

我如何将计数器递增 X 次(带动画)?类似于汽车里程表的递增方式。

您应该使用 AnimationControllerAnimatedBuilder 在控制器更改时重建您的文本。这是一个在按下浮动操作按钮时增加英里数的示例(double.toStringAsFixed 以显示小数点),动画速度曲线:

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();
  }
}

对于仍在寻找的人,您可以使用 ImplicitlyAnimatedWidget

这是一个整数计数器的例子。类似地适用于双打。

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));
  }
}

只需用新值重建小部件,它就会自动在那里设置动画。

我制作了一个关于如何在 flutter 中创建动画计数器的教程。你可以看看here

可以找到代码on this githib repository确保检查分支final_result_preview.

缺少的是十进制值,但是在您了解之后,向小部件添加小数点分隔符就不难了。

您可以使用 Countup 包。

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

https://pub.dev/packages/countup

你可以简单地使用这个插件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,
              ),
            ),