AnimatedSwitcher 没有按预期工作?小部件更改但没有动画
Posted
技术标签:
【中文标题】AnimatedSwitcher 没有按预期工作?小部件更改但没有动画【英文标题】:AnimatedSwitcher not working as intended? Widget changing but no animation 【发布时间】:2019-12-24 04:08:18 【问题描述】:目标:按下一个按钮,让它切换到另一个带有动画过渡的页面。
为此,我正在使用 AnimatedSwitcher。
下面是我的代码:
class WelcomeScreenSwitcher extends State<RandomWords>
Widget calledWidget;
void switchPage(int newNumber, context)
if (newNumber == 1)
setState(() calledWidget = welcomeScreen(context);,);
else if (newNumber == 2)
setState(() calledWidget = learnMoreScreen(context);,);
@override
Widget build(BuildContext context)
if (calledWidget == null)
switchPage(1, context);
return AnimatedSwitcher(
duration: Duration(milliseconds: 5000),
child: calledWidget,
);
Widget welcomeScreen(context)
return Scaffold(body: Column(children: [
RaisedButton(onPressed: () switchPage(2, context);, child: Text('B'),),],
);
);
Widget learnMoreScreen(context)
return Scaffold(body: Column(children: [
RaisedButton(onPressed: () switchPage(2, context);, child: Text('B'),),],
);
);
代码可以正常工作。它确实在两个页面之间切换,但没有动画。
在开发过程中的某个时刻,我得到了动画,但后来它就停止了,我不知道为什么。我不记得更改任何关于我如何调用 AnimatedSwitcher 的具体内容。
如果它有任何用处,热重载也不再起作用。我需要重新启动应用程序才能进行任何更改注册。在开始使用 AnimatedSwitcher 之前,它曾经正常运行。
【问题讨论】:
将您的方法重构为实际的类。那应该可以解决它。 @RémiRousselet 能否请您举一个小例子说明它的外观? @RémiRousselet 你能解释一下为什么这些方法不起作用,但实际类可以吗? @EmilAdz 方法不会创建新的 BuildContext。上课。 【参考方案1】:如果您要切换的新小部件与之前的小部件类型相同,请将 key
属性设置为另一个值以获取该动画
例如,这个AnimatedSwitcher
不起作用:
AnimatedSwitcher(
duration: const Duration(milliseconds: 1000),
child: (condition)
? Container(
width: 100,
height: 100,
color: Colors.red,
)
: Container(
width: 100,
height: 100,
color: Colors.blue,
),
);
因为我们要在两个Container
s 之间切换,而AnimatedSwitcher
无法理解它们的区别,所以没有动画它们的切换。
如果我们在这些Container
s 中设置不同的key
属性,那么AnimatedSwitcher
可以理解它们是不同的并且确实为它们的开关设置动画。
就像这样:
AnimatedSwitcher(
duration: const Duration(milliseconds: 1000),
child: (condition)
? Container(
key: ValueKey<int>(0),
width: 100,
height: 100,
color: Colors.red,
)
: Container(
key: ValueKey<int>(1),
width: 100,
height: 100,
color: Colors.blue,
),
);
【讨论】:
为此浪费了几个小时,谢谢!但是你怎么知道的? 他们在这里提到:youtube.com/watch?v=LKKgYpC-EPQ&ab_channel=Flutter 你救了我。非常感谢!【参考方案2】:你可以试试这个
class _AniSwitchState extends State<AniSwitch>
Widget calledWidget;
@override
Widget build(BuildContext context)
void switchPage(int newNumber)
if (newNumber == 1)
setState(() calledWidget = WelcomeScreen();,);
else if (newNumber == 2)
setState(() calledWidget = LearnMoreScreen();,);
if (calledWidget == null)
switchPage(1);
return Column(
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 2000),
child: calledWidget
),
RaisedButton(
child: const Text('Increment'),
onPressed: ()
setState(()
switchPage(2);
);
,
),
],
);
class WelcomeScreen extends StatelessWidget
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[
Text("Welcome"),
],
);
class LearnMoreScreen extends StatelessWidget
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[
Text("hello world"),
],
);
【讨论】:
它是有效的,但看起来像一些解决方法,有人有其他解决方案吗?【参考方案3】:我也遇到了这个问题,并且几天后无法解决,即使我使用 AnimatedSwitcher 的 layoutBuilder
将前面的小部件包裹在 Conrainer()
周围,我也给了我的小部件不同的键,每个小部件都给了 UniqueKey()
时间已经改变了,所以也许它会起作用,但它仍然没有用。
我的代码;
RxInt currentTab = 0.obs;
RxList<Map<String, Widget>> stepList = [
'title': Text('Adres Bilgisi'),
'view': Step1(key: ValueKey(1),)
,
'title': Text('Adres Bilgisi'),
'view': Step2(key: ValueKey(2),),
,
'title': Text('Gönderi Detayı'),
'view': Step3(key: ValueKey(3),),
].obs;
SliverToBoxAdapter(
child: Obx(() => AnimatedSwitcher(
key: Key('switcher.tab'),
duration: new Duration(microseconds: 500),
switchInCurve: Curves.easeIn,
layoutBuilder: (currentChild, previousChildren)
return Container(
key: UniqueKey(),
child: AnimatedSwitcher.defaultLayoutBuilder(currentChild, previousChildren),
);
,
transitionBuilder: (Widget child, Animation<double> animation)
/*final offsetAnimation = Tween(
begin: const Offset(1.0, 0.0),
end: const Offset(0.0, 0.0),
).animate(animation);
// 3.
return ClipRect(
child: SlideTransition(
position: offsetAnimation,
child: child,
),
);*/
return ScaleTransition(scale: animation, child: child);
,
child: controller.tabs[controller.currentTab.value.toInt()],
)),
)
这是我更改当前选定小部件的 TabBar 代码;
TabBarWidget(
height: 60,
initialSelectedId: 0,
tag: 'advertform.tab',
tabs: [
ChipWidget(
tag: 'advertform.tab',
text: "1".tr,
id: 0,
onSelected: (id)
controller.prevStep.value = controller.onStep.value;
controller.onStep.value = id;
controller.changeTab(id);
,
),
ChipWidget(
tag: 'advertform.tab',
text: "2".tr,
id: 1,
onSelected: (id)
controller.prevStep.value = controller.onStep.value;
controller.onStep.value = id;
controller.changeTab(id);
,
),
ChipWidget(
tag: 'advertform.tab',
text: "3".tr,
id: 2,
onSelected: (id)
controller.prevStep.value = controller.onStep.value;
controller.onStep.value = id;
controller.changeTab(id);
,
),
],
)
void changeTab(int index)
currentTab.value = index;
【讨论】:
以上是关于AnimatedSwitcher 没有按预期工作?小部件更改但没有动画的主要内容,如果未能解决你的问题,请参考以下文章