Comment puis-je créer un numéro d'animation compteur?

voix
1

Je voudrais créer un compteur numérique qui anime d'une valeur de départ à une valeur finale. Je l'ai regardé dans l'aide d'un minuteur mais ne peut pas sembler animer / mettre à jour correctement l'état. Y compris la valeur décimale serait grande, mais une animation simple entier est très bien.

compteur Nombre qui doit animer

double _mileCounter = 643.6;

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

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

Comment puis-je augmenter le numéro du compteur X fois (avec animation)? Semblable à la façon des incréments de l'odomètre d'une voiture.

Créé 11/05/2017 à 13:04
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
3

Vous devez utiliser un AnimationControlleravec AnimatedBuilderpour reconstruire votre texte lorsque les changements de contrôleur. Voici un exemple qui incrémente les miles lorsque le bouton d'action flottante est pressée ( double.toStringAsFixedpour tirer le décimal) pour montrer, avec une courbe de la vitesse d'animation:

capture d'écran

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();
  }
}
Créé 11/05/2017 à 17:59
source utilisateur

voix
0

Pour ceux qui cherchent encore, vous pouvez utiliser ImplicitlyAnimatedWidget.

Voici un exemple d'un compteur int. Fonctionne analogue en double.

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

Il suffit de reconstruire le widget avec une nouvelle valeur et il anime automatiquement là.

Créé 17/07/2018 à 14:35
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more