颤振AnimationController.animateBack(0)不起作用

时间:2020-10-30 08:00:21

标签: flutter dart flutter-animation

我有一个带有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));
    }
  }

0 个答案:

没有答案