我在 Flutter 演示中使用Provider来管理状态。
我想为我的小部件设置动画,但似乎 AnimateController 需要一个来自有状态小部件状态的同步参数。
据我所知,不建议将 Provider 与有状态小部件一起使用。
我可以使用 Provider 管理 AnimationController 吗?
还是必须同时使用 Provider 和有状态小部件?
我在 Flutter 演示中使用Provider来管理状态。
我想为我的小部件设置动画,但似乎 AnimateController 需要一个来自有状态小部件状态的同步参数。
据我所知,不建议将 Provider 与有状态小部件一起使用。
我可以使用 Provider 管理 AnimationController 吗?
还是必须同时使用 Provider 和有状态小部件?
我可以使用 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();
}
}
如果要在 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"),
)
],
),
),
);
}
}
我做了一个解决方法,覆盖了 didChangeDependencies 方法,该方法会在提示时触发 AnimationController.forward。
我从这个stackoverflow线程链接中得到了这个想法
@override
void didChangeDependencies() {
super.didChangeDependencies();
var result = Provider.of<Home>(context).notification;
if (result == "Play") {
_controller.forward();
}
}
但是,这只是一种解决方法,我仍在寻找一种更有效的方法来管理它(使用 Provider / 或其他解决方案,从另一个不相关的小部件开始/停止有状态小部件中的动画)。