Flutter:如何使用Provider播放动画?

时间:2019-11-03 07:49:08

标签: flutter flutter-animation flutter-provider

我使用Provider管理Flutter演示中的状态。

我想为小部件制作动画,但似乎AnimateController需要一个来自有状态小部件状态的同步参数。

据我所知,不建议Provider与有状态的小部件一起使用。

我可以使用Provider管理AnimationController吗?

还是必须同时使用提供程序和有状态小部件?

3 个答案:

答案 0 :(得分:3)

我可以使用Provider管理AnimationController吗?

还是必须同时使用提供程序和有状态小部件?

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

我在有状态窗口小部件中使用didUpdateWidget。我将值从提供程序传递给父级,并在子级中定义的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();
  }
}

答案 1 :(得分:0)

如果要在 StatelessWidget 中创建 AnimationController ,则必须在StatelessWidget的构造函数中传递 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"),
            )
          ],
        ),
      ),
    );
  }
}

答案 2 :(得分:0)

我做了一个覆盖 didChangeDependencies 方法的变通方法,该方法在提示时触发 AnimationController.forward。

我从这个 stackoverflow 线程 link

中得到了这个想法
db.users.aggregate([
    
    {$match: {role: "patient"}},
    {$lookup:
     {
       from: "messages",
       localField: "phoneNumber",
       foreignField: "phoneNumber",
       as: "messages"
     }
}

])

但是,这只是一种变通方法,我仍在寻找一种更有效的方法来管理此问题(使用 Provider / 或其他解决方案,从另一个不相关的小部件在有状态的小部件中启动/停止动画)。