Animation 在颤振动画中更新动画值的正确方法是什么?
所以我尝试在flifter中创建一个动画,每次用户按下一个按钮时需要不同的结果 我已经根据实现了以下代码,并创建了一个函数来更新它Animation 在颤振动画中更新动画值的正确方法是什么?,animation,dart,flutter,flutter-animation,Animation,Dart,Flutter,Flutter Animation,所以我尝试在flifter中创建一个动画,每次用户按下一个按钮时需要不同的结果 我已经根据实现了以下代码,并创建了一个函数来更新它 class _RoulettePageWidgetState extends State<RoulettePageWidget> with SingleTickerProviderStateMixin { Animation<double> _animation; Tween<double> _tween; An
class _RoulettePageWidgetState extends State<RoulettePageWidget>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
Tween<double> _tween;
AnimationController _animationController;
int position = 0;
@override
void initState() {
super.initState();
_animationController =
AnimationController(duration: Duration(seconds: 2), vsync: this);
_tween = Tween(begin: 0.0, end: 100.0);
_animation = _tween.animate(_animationController)
..addListener(() {
setState(() {});
});
}
void setNewPosition(int newPosition) {
_tween = Tween(
begin: 0.0,
end: math.pi*2/25*newPosition);
_animationController.reset();
_tween.animate(_animationController);
_animationController.forward();
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Center(
child: Transform.rotate(
angle: _animationController.value,
child: Icon(
Icons.arrow_upward,
size: 250.0,
),
)),
Expanded(
child: Container(),
),
RaisedButton(
child: Text('SPIN'),
onPressed: () {
setState(() {
setNewPosition(math.Random().nextInt(25));
});
},
)
],
)
);
}
}
class\u RoulettePageWidgetState扩展状态
使用SingleTickerProviderStateMixin{
动画(动画),;
吐温;
AnimationController _AnimationController;
int位置=0;
@凌驾
void initState(){
super.initState();
_动画控制器=
AnimationController(持续时间:持续时间(秒数:2),vsync:this);
_吐温=吐温(开始:0.0,结束:100.0);
_动画=_tween.animate(_animationController)
…addListener(){
setState((){});
});
}
void setNewPosition(int newPosition){
_吐温(
开始:0.0,
结束:数学pi*2/25*newPosition);
_animationController.reset();
_动画制作(_animationController);
_animationController.forward();
}
@凌驾
小部件构建(构建上下文){
返回容器(
子:列(
儿童:[
居中(
子对象:Transform.rotate(
角度:_animationController.value,
子:图标(
图标。向上箭头,
尺寸:250.0,
),
)),
扩大(
子级:容器(),
),
升起的按钮(
子项:文本('SPIN'),
已按下:(){
设置状态(){
setNewPosition(math.Random().nextInt(25));
});
},
)
],
)
);
}
}
如您所见,我正在更新之间的开始:
和结束:
,但这似乎并没有改变动画
那么,每次用户按下按钮时,我应该如何创建“不同”的动画呢
总体思路是使动画以随机新值彼此构建,例如:
- 第一次旋转:0->10
- 第二圈:10->13
- 第三圈:13->18
- 。。。等
所以我想知道我是否可以更新动画,还是应该每次都创建一个新的动画?
我能想到的另一件事是跟踪位置,每次(0.0->100.0)都使用相同的动画作为传输的百分比
因此,与其从10->15创建新动画,我将做如下操作:
currentValue=10+(15-10)/100*\u animationController.value
我将略过你的代码,集中讨论你真正想问的问题:
总体思路是使动画以随机新值彼此构建,例如:
- 第一次旋转:0->10
- 第二圈:10->13
- 第三圈:13->18
- 。。。等
对于这样的显式动画,有三个对象是您感兴趣的:
- 控制器,这是一种特殊类型的动画,仅从其下限到上限线性生成值(双倍,通常为0.0和1.0)。您可以控制动画的流程-向前发送、反转、停止或重置动画
- 这不是一个动画,而是一个动画。tween定义了两个值之间的插值,这两个值甚至不必是数字。它在引擎盖下实现了一个
transform
方法,该方法接收动画的当前值,并输出您想要处理的实际值:另一个数字、一种颜色、一个线性渐变,甚至是一个完整的小部件。这是你应该用来生成旋转角度的
- 一个动画,这是一个你实际要使用其值的动画(因此,这是你获取要使用的值的地方)。你可以通过给你的孩子一个要变换的父动画来实现这一点——这可能是你的控制器,但也可以是你在其上构建的其他类型的动画(比如曲线动画,它可以给你缓和或弹性/弹性曲线等等)。颤振的动画是高度可组合的方式
您的代码之所以失败,主要是因为您实际上没有使用在构建方法中创建的顶级动画,并且每次调用setNewPosition
时都在创建一个新的tween和动画。您可以对多个动画“循环”使用相同的tween和动画-只需更改现有tween的begin
和end
属性,它就会在动画中出现气泡。结果是这样的:
class _RoulettePageWidgetState extends State<RoulettePageWidget>
with SingleTickerProviderStateMixin {
Animation<double> _animation;
Tween<double> _tween;
AnimationController _animationController;
math.Random _random = math.Random();
int position = 0;
double getRandomAngle() {
return math.pi * 2 / 25 * _random.nextInt(25);
}
@override
void initState() {
super.initState();
_animationController =
AnimationController(duration: Duration(seconds: 2), vsync: this);
_tween = Tween(begin: 0.0, end: getRandomAngle());
_animation = _tween.animate(_animationController)
..addListener(() {
setState(() {});
});
}
void setNewPosition() {
_tween.begin = _tween.end;
_animationController.reset();
_tween.end = getRandomAngle();
_animationController.forward();
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Center(
child: Transform.rotate(
angle: _animation.value,
child: Icon(
Icons.arrow_upward,
size: 250.0,
),
)),
Expanded(
child: Container(),
),
RaisedButton(
child: Text('SPIN'),
onPressed: setNewPosition,
)
],
)
);
}
}
class\u RoulettePageWidgetState扩展状态
使用SingleTickerProviderStateMixin{
动画(动画),;
吐温;
AnimationController _AnimationController;
math.Random _Random=math.Random();
int位置=0;
double getRandomAngle(){
返回math.pi*2/25*_random.nextInt(25);
}
@凌驾
void initState(){
super.initState();
_动画控制器=
AnimationController(持续时间:持续时间(秒数:2),vsync:this);
_tween=tween(开始:0.0,结束:getRandomAngle());
_动画=_tween.animate(_animationController)
…addListener(){
setState((){});
});
}
void setNewPosition(){
_tween.begin=\u tween.end;
_animationController.reset();
_tween.end=getRandomAngle();
_animationController.forward();
}
@凌驾
小部件构建(构建上下文){
返回容器(
子:列(
儿童:[
居中(
子对象:Transform.rotate(
角度:_animation.va
..addListener(() {
setState(() {});
});
class RotationExample extends StatefulWidget {
final Widget child;
const RotationExample({
Key key,
this.child,
}) : super(key: key);
@override
RotationExampleState createState() {
return new RotationExampleState();
}
}
class RotationExampleState extends State<RotationExample> {
final _random = math.Random();
double rad = 0.0;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _rotate,
child: AnimatedTransform(
duration: const Duration(seconds: 1),
alignment: Alignment.center,
transform: Matrix4.rotationZ(rad),
child: Container(
color: Colors.red,
height: 42.0,
width: 42.0,
),
),
);
}
void _rotate() {
setState(() {
rad = math.pi * 2 / 25 * _random.nextInt(25);
});
}
}
class AnimatedTransform extends ImplicitlyAnimatedWidget {
final Matrix4 transform;
final AlignmentGeometry alignment;
final bool transformHitTests;
final Offset origin;
final Widget child;
const AnimatedTransform({
Key key,
@required this.transform,
@required Duration duration,
this.alignment,
this.transformHitTests = true,
this.origin,
this.child,
Curve curve = Curves.linear,
}) : assert(transform != null),
assert(duration != null),
super(
key: key,
duration: duration,
curve: curve,
);
@override
_AnimatedTransformState createState() => _AnimatedTransformState();
}
class _AnimatedTransformState
extends AnimatedWidgetBaseState<AnimatedTransform> {
Matrix4Tween _transform;
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
_transform = visitor(_transform, widget.transform,
(dynamic value) => Matrix4Tween(begin: value));
}
@override
Widget build(BuildContext context) {
return Transform(
alignment: widget.alignment,
transform: _transform.evaluate(animation),
transformHitTests: widget.transformHitTests,
origin: widget.origin,
child: widget.child,
);
}
}