如何解决在Flutter中创建自定义动画的正确方法
我有点困惑我可以在Flutter中处理自定义动画。让我们来看一个例子。我想创建一个跳动动画,其中一个圆圈变大并返回其原始大小,我希望该动画重复2次。我认为Sin功能非常适合实现我的目的,但绝对有价值。现在,我找到了三种获取结果的可能方法:
- 使用AnimatedBuilder / AnimatedWidget
const holders = new Map<DataType,holders>();
const currentTypes: DataType[] = [];
function getDataHolder(type: DataType.POINT): PointHolder;
function getDataHolder(type: DataType.LINE): LineHolder;
function getDataHolder(type: DataType): holders {
if (!holders.has(type)) {
holders.set(type,DataHolder.factory(type));
currentTypes.push(type);
}
return holders.get(type);
}
function add(type: DataType.POINT,ids: number): void;
function add(type: DataType.LINE,ids: number[]): void;
function add(type: DataType,ids: number | number[]): void {
let hldr: holders;
switch (type) {
case DataType.POINT:
hldr = getDataHolder(type);
hldr.add(ids); // Argument of type 'number | number[]' is not assignable to parameter of type 'number'.
break;
case DataType.LINE: {
hldr = getDataHolder(type);
hldr.add(ids); // Argument of type 'number | number[]' is not assignable to parameter of type 'number[]'.
break;
}
default:
break;
}
}
function clear() {
for (const type of currentTypes) {
const hldr = getDataHolder(type); // No overload matches this call
hldr.clear();
}
}
使用此类,我可以创建一个动画控制器,将其传递给我的BounceTransition,并获得弹跳的效果。
2)创建自定义补间
class BounceTransition extends AnimatedWidget {
final int blinkCount;
final int offset;
final Widget child;
final Alignment alignment;
BlinkTransition({
Key key,@required Animation<double> animation,this.alignment = Alignment.center,this.child,this.blinkCount = 2,this.offset = 1,}) : super(key: key,listenable: animation);
Animation<double> anim() => listenable as Animation<double>;
@override
Widget build(BuildContext context) {
double value = anim().value * pi * blinkCount;
final double scaleValue = sin(value).abs() + offset;
final Matrix4 transform = Matrix4.identity()
..scale(scaleValue,scaleValue,1.0);
return Transform(
transform: transform,alignment: alignment,child: child,);
}
}
有了这个自定义的Tween,我可以创建一个ScaleTransition
class SinTween extends Animatable<double> {
final double begin;
final double end;
final double offset;
SinTween({this.begin,this.end,this.offset = 1});
@override
double transform(double t) {
if (t == 0.0) return begin + offset;
if (t == 1.0 + offset) return end;
return this.lerp(t);
}
@protected
double lerp(double t) {
return sin(begin + (end - begin) * t).abs() + offset;
}
}
- 我发现的最后一种方法是创建自定义曲线
AnimationController _animationController = AnimationController(vsync: this,duration: Duration(milliseconds: 500));
Animation<double> _animation = SinTween(begin: 0,end: pi * 2,offset: 1).animate(CurvedAnimation(parent: _animationController,curve: Curves.easeOut));
.
.
.
ScaleTransition(
scale: _animation,child: Container(...),),.
.
.
通过此类,我可以创建一个使用这种曲线的动画控制器。
class SinCurve extends Curve {
@override
double transformInternal(double t) {
var val = sin(1 * 2 * pi * t).abs() + 1;
return val; //f(x)
}
}
所以我的问题是:正确的方法是什么?创建AnimatedWidget时,创建自定义动画或创建自定义曲线吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。