Flutter 如果之前具有异步功能,则动画不工作

Flutter 如果之前具有异步功能,则动画不工作,flutter,Flutter,我的动画根本没有启动,在名为waitForAnimationComplete()的超时函数的整个4秒钟内,屏幕都是白色的。 最有趣的是,在热重新加载的情况下,一切都很完美,但在第一次启动时,什么都没有,屏幕是白色的 不幸的是,发布应用程序没有热重新加载,所以我不能忽略这个问题 此视图中的想法是从白色屏幕开始,然后(在计算颜色后)通过从白色到颜色的动画慢慢更改为彩色视图 import 'package:flutter/material.dart'; import 'package:my_proje

我的动画根本没有启动,在名为
waitForAnimationComplete()的超时函数的整个4秒钟内,屏幕都是白色的。

最有趣的是,在热重新加载的情况下,一切都很完美,但在第一次启动时,什么都没有,屏幕是白色的

不幸的是,发布应用程序没有热重新加载,所以我不能忽略这个问题

此视图中的想法是从白色屏幕开始,然后(在计算颜色后)通过从白色到颜色的动画慢慢更改为彩色视图

import 'package:flutter/material.dart';
import 'package:my_project/home/home.dart';
import 'package:my_project/stile/theme_colors.dart';

class LoadingHome extends StatefulWidget {
  @override
  _LoadingHomeState createState() => _LoadingHomeState();
}

class _LoadingHomeState extends State<LoadingHome> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<Color> background;

  @override
  void initState(){
    super.initState();
    controller = AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);

    openHome();
  }

  openHome() async{
    double hue = await recoverColor();
    startTransition(hue);

    await Future.wait([waitForAnimationComplete()]);
    Navigator.pushReplacement(
        context, MaterialPageRoute(builder: (BuildContext context) => Home())
    );
  }

  Future<double> recoverColor() async {
    return 0.6;
  }

  startTransition(double hue) {
    if(hue == null)
      ThemeColors.initColors();
    else
      ThemeColors.initColors(hue: hue);

    background = ColorTween(
      begin: Colors.white,
      end: ThemeColors.dark,
    ).animate(controller);
    controller.forward(); // starts animation
  }

  Future<void> waitForAnimationComplete() async {
    await Future.delayed(const Duration(seconds: 4));
  }

  @override
  Widget build(BuildContext context) {
    return controller.isAnimating ? AnimatedBuilder(
      animation: background,
      builder: (BuildContext context, child) => BodyLoadHome(
        background: background.value,
      ),
    ) : BodyLoadHome(
      background: Colors.white,
    );
  }
}

class BodyLoadHome extends StatelessWidget {
  final Color background;

  BodyLoadHome({this.background});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: background,
    );
  }
}

有了这些变化,一切都正常了。显然,真正的
recoverColor()
并不是那么简单,在这个函数中,我应该从内部存储器中读取色调,因此
recoverColor()
一定是未来的趋势

我怎样才能使它即使在将来也能工作呢
recoverColor()

编辑:

建议将
.addListener()
setState()
结合使用,但我认为我找到了一个更有效但类似的解决方案:

更改:

controller.forward(); // starts animation
致:


因此,我们只需调用一次
setState()
,即可从
BodyLoadHome
更改为
AnimatedBuilder
。我认为当使用
AnimatedBuilder
时,他会在需要时调用
setState()
当动画位置发生变化时,您忘记调用
setState
。因此,您永远看不到UI中的更改。在
initState
中创建控制器时,向
AnimationController
添加一个调用
setState
的侦听器

controller.addListener((){
setState((){});
});

你可以阅读官方的颤振教程来学习颤振动画的基本知识。

在调用
forward()
之后,你必须调用
setState
,以便你的小部件构建
AnimatedBuilder
而不是
BodyLoadHome
,同时检查
controller.forward()
返回并用于延迟调用
Navigator.pushReplacement
但老实说,我总是返回
AnimatedBuilder
,以简化代码,或者更好的
AnimatedContainer
有两种不同的
颜色:
值谢谢,但我更喜欢看到加载屏幕至少4秒。我认为总是
AnimatedBuilder
不容易使用,因为构造函数中使用
background
,而
background
在开始时为空不需要在每个动画帧中调用
addListener
并调用
setState
-动画由
AnimatedBuilder
处理-真正的问题是,自上一次
build()以来,没有生成
方法返回
BodyLoadHome
作为
控制器。isAnimating
false
-这就是为什么我说总是返回
动画生成器
controller.forward(); // starts animation
setState(() {
      controller.forward(); // starts animation
    });