我有一个带有ZoomIn
动画的小部件,然后在其上调用了animateBack(0)
,但它没有缩小。我可以确认使用同一动画控制器调用了animateBack(0)
,因为我在执行animateBack(0)
的代码中添加了一个断点。
以下是此代码块的执行位置:
zoomStream.listen((dynamic event) {
zoomController.animateBack(0,
duration: const Duration(milliseconds: 500));
});
为什么不重新制作动画?它曾经可以工作,但是自那以后我重构了我的代码以使用流,尽管它们确实执行了流,所以我不认为这是问题所在。
小部件:
import 'package:animate_do/animate_do.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:vepo/presentation/animations/pulse_animation.dart';
import 'pulse_on_change_animation_controller.dart';
class VpPulseOnChangeAnimation extends StatelessWidget {
VpPulseOnChangeAnimation(this.field, {this.child}) {
controller = Get.put(VpPulseOnChangeAnimationController(field));
}
final ReactiveFormFieldState<String> field;
final Widget child;
VpPulseOnChangeAnimationController controller;
@override
Widget build(BuildContext context) {
if (controller.firstLoad) {
return Container();
} else {
return ZoomIn(
duration: const Duration(milliseconds: 250),
controller: (AnimationController zoomAnimationController) =>
{controller.zoomController = zoomAnimationController},
child: VpPulse(
manualTrigger: true,
controller: (AnimationController pulseAnimationController) =>
{controller.pulseController = pulseAnimationController},
duration: const Duration(milliseconds: 70),
child: child));
}
}
}
小部件的控制器:
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:reactive_forms/reactive_forms.dart';
class VpPulseOnChangeAnimationController extends GetxController {
AnimationController pulseController;
AnimationController zoomController;
bool firstLoad = true;
ReactiveFormFieldState<String> field;
@override
void onInit() {}
@override
void onReady() {
field.control.valueChanges.first.then((dynamic value) => firstLoad = false);
final pulseStream = field.control.valueChanges
.where((dynamic val) => (val as String).length < 20)
.where((dynamic val) => (val as String).isNotEmpty)
.where((dynamic val) => pulseController != null)
.where((dynamic val) => !pulseController.isAnimating);
final zoomStream = field.control.valueChanges
.where((dynamic val) => (val as String).isEmpty)
.where((dynamic val) => zoomController != null)
.where((dynamic val) => !zoomController.isAnimating);
pulseStream.listen((dynamic event) {
pulseController.forward(from: 0);
});
zoomStream.listen((dynamic event) {
zoomController.animateBack(0,
duration: const Duration(milliseconds: 500));
});
}
@override
void onClose() {}
}
调试内部不稳定的第三方程序包animation_controller.dart,
我的代码进入这里:
} else if (target == value) {
// Already at target, don't animate.
simulationDuration = Duration.zero;
}
animationController(zoomController
)的值在第一次设置动画时应该设为1。但是,它没有这样做。但是它确实可以进行动画处理。因此,zoomController
可能与动画中的动画有所不同。
我的旧方法行之有效,但势在必行:
在控制器中:
// ignore: avoid_void_async
void applyAppropriateAnimations(String field) async {
await Future.delayed(const Duration(milliseconds: 0), () {});
if (pulseController != null &&
!pulseController.isAnimating &&
field != null &&
field.length > 1) {
await pulseController.forward(from: 0);
} else {
if (zoomController != null &&
!zoomController.isAnimating &&
field.isEmpty) {
zoomController.animateBack(0);
}
}
}
在小部件中:
@override
Widget build(BuildContext context) {
controller.applyAppropriateAnimations(field.value as String);
if (controller.firstLoad) {
return Container();
} else {
return ZoomIn(
manualTrigger: true,
duration: const Duration(milliseconds: 250),
controller: (AnimationController zoomAnimationController) =>
{controller.zoomController = zoomAnimationController},
child: VpPulse(
manualTrigger: true,
controller: (AnimationController pulseAnimationController) =>
{controller.pulseController = pulseAnimationController},
duration: const Duration(milliseconds: 70),
child: child));
}
}