Flutter 颤振动画控制器。动画回退(0)不工作

Flutter 颤振动画控制器。动画回退(0)不工作,flutter,dart,flutter-animation,Flutter,Dart,Flutter Animation,我有一个带有缩放动画的小部件,然后我在上面调用动画回退(0),它不会缩小。我可以确认使用相同的动画控制器调用了animateBack(0),因为我在执行animateBack(0)的代码中放置了一个断点 这里的代码块是它执行它的地方: zoomStream.listen((dynamic event) { zoomController.animateBack(0, duration: const Duration(milliseconds: 500)); }); 为什么它不能重

我有一个带有
缩放
动画的小部件,然后我在上面调用
动画回退(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() {}
}
  @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));
    }
  }
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);
      }
    }
  }
在小部件中:

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() {}
}
  @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));
    }
  }