12

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

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

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

我可以使用 Provider 管理 AnimationController 吗?

还是必须同时使用 Provider 和有状态小部件?

4

3 回答 3

4

我可以使用 Provider 管理 AnimationController 吗?

还是必须同时使用 Provider 和有状态小部件?

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

我在有状态小部件中使用didUpdateWidget。我将值从提供程序传递给父项,并didUpdateWidget在子项中定义的方法中触发动画。didUpdateWidget当我通知听众 Provider 发生变化时,它会自行触发。

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();
  }
}
于 2020-04-25T09:00:14.050 回答
1

如果要在 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"),
            )
          ],
        ),
      ),
    );
  }
}
于 2020-07-02T13:43:55.110 回答
0

我做了一个解决方法,覆盖了 didChangeDependencies 方法,该方法会在提示时触发 AnimationController.forward。

我从这个stackoverflow线程链接中得到了这个想法

@override
  void didChangeDependencies() {
    super.didChangeDependencies();

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

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

于 2021-06-08T02:58:55.710 回答