flutter 如何将GetX中的动画控制器与GetTickerProviderStateMixin结合使用

sqserrrh  于 2022-12-24  发布在  Flutter
关注(0)|答案(2)|浏览(795)

我想用GetxController和GetView在flutter中实现动画,以控制每个小部件中的动画,这是我的Getx控制器:

class TestAnimationController extends GetxController
    with GetTickerProviderStateMixin {
  late AnimationController anim;
  late Animation<double> animation;
  @override
  void onInit() {
    super.onInit();
    initAnimation();
    anim.forward();
  }

  void initAnimation() {
    anim = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    );
    animation = Tween<double>(begin: 1, end: 0).animate(
      CurvedAnimation(
        parent: anim,
        curve: Interval(0.0, 1.0, curve: Curves.linear),
      ),
    );
  }
}

我的GetView类是:

class TestAnimationHome extends GetView<TestAnimationController> {
  const TestAnimationHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          width: controller.animation.value + 100,
          height: controller.animation.value + 100,
          color: Colors.amber,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          controller.anim.forward();
        },
        child: Icon(
          Icons.play_circle,
        ),
      ),
    );
  }
}

我谷歌了很多,做每一步提到,但我的动画不开始,我不知道我做错了!

6l7fqoea

6l7fqoea1#

你面临这个问题是因为你没有告诉UI显式地绘制(例如setstate)。你可以在GetX中看到下面的实现。
我在UI部分使用了addListener函数沿着GetBuilder

class TestAnimationController extends GetxController
    with GetTickerProviderStateMixin {
  late AnimationController anim;
  late Animation<double> animation;
  @override
  void onInit() {
    initAnimation();
    anim.forward();
    super.onInit();
  }

  void initAnimation() {
    anim = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    );
    animation = Tween<double>(begin: 10, end: 100).animate(
      CurvedAnimation(
        parent: anim,
        curve: Interval(0.0, 1.0, curve: Curves.linear),
      ),
    )..addListener(() {
        update();
      });
  }
}

class TestAnimationHome extends StatelessWidget {
  const TestAnimationHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GetBuilder<TestAnimationController>(
        init: TestAnimationController(),
        initState: (_) {},
        builder: (controller) {
          return Center(
            child: Container(
              width: controller.animation.value + 100,
              height: controller.animation.value + 100,
              color: Colors.amber,
            ),
          );
        },
      ),
      floatingActionButton: GetBuilder<TestAnimationController>(
        builder: (controller) {
          return FloatingActionButton(
            onPressed: () {
              controller.anim.forward();
              controller.update();
            },
            child: const Icon(
              Icons.play_circle,
            ),
          );
        },
      ),
    );
  }
}

希望能回答你的问题😄

anauzrmj

anauzrmj2#

除了我从@cavin-macwan的回答中学到的东西,我想提一下我的一些错误,让任何有同样问题的人更好地理解。
首先,我们需要GetBiulder来跟踪控制器中的任何更新,当您将“addListener”添加到动画中并使用它更新控制器时,GetBuilder将正确更新UI。
另一个错误是Tween<double>(begin: 1, end: 0),导致Containerwidth:仅改变1 px,因此您无法看到实际发生的变化。将Tween<double>(begin: 1, end: 0)改变为Tween<double>(begin: 0, end: 100)或将Container的尺寸从width: c.animation.value + 100,改变为width: c.animation.value * 100,
floatingActionButton中不需要controller.update();,因为addListener在控制器中的任何AnimationController滴答声之后执行此操作。
与在floatingActionButton中使用GetBuilder相比,我更喜欢使用extends GetView<TestAnimationController>,因为代码较少。

相关问题