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