颤动动画如何逐渐淡入/淡出
问题描述:
我从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(),
)
),
);
}
对不起,我的代码大块,我不确定我能弄错了其中的一部分。
答
我认为你是在正确的轨道上,但你应该只使用一个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(),
)
),
);
}
}
你可以尝试使用AnimatedOpacity而不是透明度?只是一个想法 :) –