颤动动画如何逐渐淡入/淡出

Gya*_*nji 5 dart flutter

我开始使用 Flutter 并尝试制作一个在连续淡入淡出的同时旋转的动画。到目前为止旋转有效,但我在褪色效果方面遇到困难。小部件将逐渐变得透明,但在旋转一圈后,它会跳回到不透明状态,然后再次变为透明。我正在尝试解决此问题,但似乎无法找到方法。使用.forward().reverse()不起作用,但我可能错误地实现了不透明动画。

class AnimatedLoader extends AnimatedWidget {
  static final _opacityTween = new Tween<double>(begin: 1.0, end: 0.3);

  AnimatedLoader({
    Key key,
    this.alignment: FractionalOffset.center,
    Animation<double> turns,
    Animation<double> animation,
    this.child,
  }) : super(key: key, listenable: turns);

  Animation<double> get turns => listenable;

  final FractionalOffset alignment;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    final double turnsValue = turns.value;
    final Matrix4 transform = new Matrix4.rotationZ(turnsValue * math.PI * 2.0);
    return new Transform(
      alignment: alignment,
      transform: transform,
      child: new Opacity(
        opacity: _opacityTween.evaluate(animation),
        child: child,
      )
    );
  }
}

class AppLoader extends StatefulWidget {
  AppLoaderState createState() => new AppLoaderState();
}

class AppLoaderState extends State<AppLoader> with TickerProviderStateMixin {
  AnimationController _controller;
  AnimationController _controllerOp;
  Animation<double> animation;

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

    _controllerOp = new AnimationController(
      duration: const Duration(milliseconds: 800),
      vsync: this,
    );
    animation = new Tween(begin: 0.0, end: 300.0).animate(_controllerOp);

    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _controllerOp.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controllerOp.forward();
      }
    });
    _controllerOp.forward();
  }

  @override
  Widget build(BuildContext context) {
    return new Center (
      child: new AnimatedLoader(
        turns: _controller,
        alignment: FractionalOffset.center,
        animation: _controllerOp,
        child: new Container(
          margin: new EdgeInsets.symmetric(vertical: 10.0),
          height: 150.0,
          width: 150.0,
          child: new FlutterLogo(),
        )
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

很抱歉有一大段代码,我不确定我可能在哪个部分犯了错误。

Col*_*son 3

我认为您走在正确的道路上,但AnimationController每个AnimatedWidget. 我修复了您代码中的一些错误。

脉动颤动标志的视频

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new AppLoader(),
    );
  }
}

class PulsateCurve extends Curve {
  @override
  double transform(double t) {
    if (t == 0 || t == 1)
      return 0.3;
    return math.sin(t * math.PI) * 0.35 + 0.65;
  }
}

class AnimatedLoader extends AnimatedWidget {
  static final _opacityTween = new CurveTween(curve: new PulsateCurve());

  AnimatedLoader({
    Key key,
    this.alignment: FractionalOffset.center,
    Animation<double> animation,
    this.child,
  }) : super(key: key, listenable: animation);

  final FractionalOffset alignment;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    final Matrix4 transform = new Matrix4.rotationZ(animation.value * math.PI * 2.0);
    return new Transform(
        alignment: alignment,
        transform: transform,
        child: new Opacity(
          opacity: _opacityTween.evaluate(animation),
          child: child,
        )
    );
  }
}

class AppLoader extends StatefulWidget {
  AppLoaderState createState() => new AppLoaderState();
}

class AppLoaderState extends State<AppLoader> with TickerProviderStateMixin {
  AnimationController _controller;

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

  @override
  Widget build(BuildContext context) {
    return new Center (
      child: new AnimatedLoader(
          animation: _controller,
          alignment: FractionalOffset.center,
          child: new Container(
            margin: new EdgeInsets.symmetric(vertical: 10.0),
            height: 150.0,
            width: 150.0,
            child: new FlutterLogo(),
          )
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)