AnimatedSwitcher 没有按预期工作?小部件更改但没有动画
AnimatedSwitcher not working as intended? Widget changing but no animation
目标:按下一个按钮,让它切换到另一个带有动画过渡的页面。
为此,我正在使用 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 之前,它曾经正常运行。
你可以试试这个
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"),
],
);
}
}
如果您要切换的新小部件与之前的小部件类型相同,请将 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
之间切换,而AnimatedSwitcher
无法理解它们的区别,所以它没有动画它们的切换。
如果我们在那些 Container
中设置不同的 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,
),
);
我也有这个问题,几天后无法解决,我给了我的小部件不同的键,即使我使用 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。
下面是我的代码:
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 之前,它曾经正常运行。
你可以试试这个
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"),
],
);
}
}
如果您要切换的新小部件与之前的小部件类型相同,请将 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
之间切换,而AnimatedSwitcher
无法理解它们的区别,所以它没有动画它们的切换。
如果我们在那些 Container
中设置不同的 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,
),
);
我也有这个问题,几天后无法解决,我给了我的小部件不同的键,即使我使用 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;
}