Flutter 颤振:如何与供应商播放动画?

Flutter 颤振:如何与供应商播放动画?,flutter,flutter-animation,flutter-provider,Flutter,Flutter Animation,Flutter Provider,我在颤振演示中用于管理状态 我想为我的小部件设置动画,但AnimateControl似乎需要一个来自有状态小部件状态的同步参数 据我所知,不建议将提供程序与有状态小部件一起使用 我可以使用提供程序管理AnimationController吗 或者必须同时使用提供程序和有状态小部件 我可以使用提供程序管理AnimationController吗 或者必须同时使用提供程序和有状态小部件 我不知道这是否是最好的方法,但我是这样做的: 我在有状态小部件中使用。我将值从提供者传递给父对象,并在子对象中定义

我在颤振演示中用于管理状态

我想为我的小部件设置动画,但AnimateControl似乎需要一个来自有状态小部件状态的同步参数

据我所知,不建议将提供程序与有状态小部件一起使用

我可以使用提供程序管理AnimationController吗

或者必须同时使用提供程序和有状态小部件

我可以使用提供程序管理AnimationController吗

或者必须同时使用提供程序和有状态小部件

我不知道这是否是最好的方法,但我是这样做的:

我在有状态小部件中使用。我将值从提供者传递给父对象,并在子对象中定义的
didUpdateWidget
方法中触发动画<代码>didUpdateWidget在我从提供程序中的更改通知侦听器时被触发

class MyWidget extends StatefulWidget {
  final String valueFromProvider;

  MyWidget({this.valueFromProvider});

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with TickerProviderStateMixin {
  @override
  void didUpdateWidget(MyWidget oldWidget) {
    // TODO: implement didUpdateWidget
    super.didUpdateWidget(oldWidget);

    if (oldWidget.valueFromProvider == "whatever you want" &&
        widget.valueFromProvider == "what you want that changed") {
      // trigger animations methods here
    }
  }

  // here all the animations methods,dispose method, etc. 

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
类MyWidget扩展了StatefulWidget{
提供程序的最终字符串值;
MyWidget({this.valueFromProvider});
@凌驾
_MyWidgetState createState()=>\u MyWidgetState();
}
类_MyWidgetState使用TickerProviderStateMixin扩展状态{
@凌驾
void didUpdateWidget(MyWidget oldWidget){
//TODO:实现didUpdateWidget
super.didUpdateWidget(oldWidget);
如果(oldWidget.valueFromProvider==“您想要什么”&&
widget.valueFromProvider==“您希望更改的内容”){
//在这里触发动画方法
}
}
//这里介绍了所有的动画方法、处理方法等。
@凌驾
小部件构建(构建上下文){
返回容器();
}
}

如果要在无状态小部件中创建AnimationController,必须在无状态小部件的构造函数中传递TickerProviderStateMixin,请查看我的示例代码:

import 'package:flutter/material.dart';

main() {
  runApp(TestyApp());
}

class TestyApp extends StatefulWidget {
  @override
  _TestyAppState createState() => _TestyAppState();
}

class _TestyAppState extends State<TestyApp> with TickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TestAnimationInStatelessWidget(
        tickerProviderStateMixin: this,
      ),
    );
  }
}

class TestAnimationInStatelessWidget extends StatelessWidget {
  final TickerProviderStateMixin tickerProviderStateMixin;

  const TestAnimationInStatelessWidget(
      {Key key, @required this.tickerProviderStateMixin})
      : assert(tickerProviderStateMixin != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {

    var _animationController = AnimationController(
        vsync: tickerProviderStateMixin, duration: Duration(seconds: 1));

    var _animation = Tween<double>(begin: 0, end: 2).animate(CurvedAnimation(
        parent: _animationController, curve: Curves.easeInOut));

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            RotationTransition(
              turns: _animation,
              child: Container(
                width: 200,
                height: 200,
                decoration: BoxDecoration(
                  color: Colors.blueGrey,
                  borderRadius: BorderRadius.all(Radius.circular(15)),
                ),
              ),
            ),
            SizedBox(
              height: 30,
            ),
            RaisedButton(
              onPressed: () {
                _animationController.reset();
                _animationController.forward();
              },
              child: Text("Start Animation"),
            )
          ],
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
main(){
runApp(TestyApp());
}
类TestyApp扩展了StatefulWidget{
@凌驾
_TestyAppState createState()=>\u TestyAppState();
}
类_TestyAppState使用TickerProviderStateMixin扩展状态{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:TestAnimationInStatelessWidget(
tickerProviderStateMixin:这个,
),
);
}
}
类TestAnimationInStatelessWidget扩展了无状态Widget{
最终票证ProviderStateMixin票证ProviderStateMixin;
const Testanimation InstatelessWidget(
{Key Key,@required this.tickerProviderStateMixin})
:assert(tickerProviderStateMixin!=null),
超级(键:键);
@凌驾
小部件构建(构建上下文){
var\u animationController=animationController(
vsync:tickerProviderStateMixin,持续时间:持续时间(秒:1));
var_animation=Tween(开始:0,结束:2)。动画(曲线动画)(
父对象:_animationController,曲线:Curves.easeInOut);
返回脚手架(
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
旋转跃迁(
旋转:_动画,
子:容器(
宽度:200,
身高:200,
装饰:盒子装饰(
颜色:颜色。蓝灰色,
borderRadius:borderRadius.all(半径.圆形(15)),
),
),
),
大小盒子(
身高:30,
),
升起的按钮(
已按下:(){
_animationController.reset();
_animationController.forward();
},
子项:文本(“开始动画”),
)
],
),
),
);
}
}

我做了一个关于重写didChangeDependencies方法的工作,该方法在提示时触发AnimationController.forward

我是从这个帖子里得到这个主意的

@覆盖
void didChangeDependencies(){
super.didChangeDependencies();
var result=Provider.of(context).notification;
如果(结果=“播放”){
_controller.forward();
}
}

然而,这只是一个解决办法,我仍在寻找一种更有效的方法来管理它(使用提供者/或其他解决方案,从另一个不相关的小部件在有状态的小部件中启动/停止动画)。

动画属于用户界面,而不是状态。您需要为动画控制器提供一个Ticker。您可以使用SingleTickerProviderStateMixin来避免手动创建它@RicardoMarkiewicz如果我想从同一个孩子的另一个孩子那里触发一个动画呢parent@RicardoMarkiewicz但我们都同意状态定义UI?我认为Javan想知道当小部件树被破坏时,如何在状态改变时制作漂亮的动画。提供程序很容易处理,但状态更改时小部件的即时切换很奇怪。你如何解决这个问题?假设您推送登录,应用程序开始登录,然后切换到下载配置文件,下载这个和那个,最后显示最终登录界面?您的动画控制器应该在UI部分,而不是状态类中,因为动画不是应用程序状态的一部分(例如,您的使用是否已登录?)但UI的部分瞬态(当您离开该屏幕时,状态会丢失)。您需要使用boh提供程序和StatefulWidget,您可以使用AnimatedWidget,您可以使用FlatterHooks,但永远不要从状态/模式类管理您的动画。在您的示例中,您使用的是StatefulWidget。
@override
  void didChangeDependencies() {
    super.didChangeDependencies();

    var result = Provider.of<Home>(context).notification;
    if (result == "Play") {
      _controller.forward();
    }
  }