在脚手架中使用动画在 PageView 页面上使用 Flutter 切换 FAB
Flutter Switching FAB on PageView Pages with animation in Scaffold
因此,我已经查看了几个地方以了解应该如何实现它,我确定我遗漏了一些微不足道的东西,但我有一个 flutter 应用程序,其主体是一个 PageView 的脚手架。我需要为某些页面设置不同的 FAB,目前的设置方式是将脚手架的 floatingActionButton 属性设置为访问 FloatingActionButtons 数组,索引为 _currentPageIndex(由 bottomNavBar 和 _pageController 共享的私有变量。
这会突然更改 FAB,这不是所需的行为。
我正在尝试让 FAB 在页面发生变化(如 material spec:
时动画化(扩展和缩减)
Tabbed Screens
When tabs are present, the FAB should briefly disappear, then >reappear when the new content moves into place. This expresses >that the FAB is not connected to any particular tab.
对于如何简单地实施它的任何建议,我将不胜感激(我很确定我遗漏了一些微不足道的东西)。另一种方法是通过将 FAB 包裹在某种东西中来手动制作 FAB 的进出动画。
您可以尝试使用像这样的 AnimatedCrossFade
小部件:
class TestingNewWidgetState extends State<TestingNewWidget> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: AnimatedCrossFade(
crossFadeState: currentIndex == 0
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
firstChild: FloatingActionButton(
onPressed: () => null,
child: Icon(Icons.arrow_left),
backgroundColor: Colors.red,
),
secondChild: FloatingActionButton(
onPressed: () => null,
child: Icon(Icons.arrow_right),
backgroundColor: Colors.blue,
),
),
body: PageView(
onPageChanged: (index) {
setState(() {
currentIndex = index;
});
},
children: <Widget>[
Scaffold(
body: Center(
child: Text("page 1"),
),
),
Scaffold(
body: Center(
child: Text("page 2"),
),
),
],
),
);
}
}
更新
请记住,您可以创建自己的小部件,这是一个使用自定义 FloatingActionButton
的示例:
class TestingNewWidgetState extends State<TestingNewWidget> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
var customFabButton;
if (currentIndex == 0) {
customFabButton = CustomFabButton(
color: Colors.red,
onPressed: () => null,
icon: Icons.alarm,
);
} else if (currentIndex == 1) {
customFabButton = CustomFabButton(
color: Colors.blue,
onPressed: () => null,
icon: Icons.satellite,
);
} else {
customFabButton = CustomFabButton(
color: Colors.green,
onPressed: () => null,
icon: Icons.verified_user,
);
}
return Scaffold(
floatingActionButton: customFabButton,
body: PageView(
onPageChanged: (index) {
setState(() {
currentIndex = index;
});
},
children: <Widget>[
Scaffold(
body: Center(
child: Text("page 1"),
),
),
Scaffold(
body: Center(
child: Text("page 2"),
),
),
Scaffold(
body: Center(
child: Text("page 3"),
),
),
],
),
);
}
}
class CustomFabButton extends StatelessWidget {
final IconData icon;
final Color color;
final VoidCallback onPressed;
const CustomFabButton({Key key, this.icon, this.color, this.onPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: AnimatedContainer(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color,
),
duration: Duration(seconds: 1),
height: 50.0,
width: 50.0,
child: Icon(icon),
),
);
}
}
因此,我已经查看了几个地方以了解应该如何实现它,我确定我遗漏了一些微不足道的东西,但我有一个 flutter 应用程序,其主体是一个 PageView 的脚手架。我需要为某些页面设置不同的 FAB,目前的设置方式是将脚手架的 floatingActionButton 属性设置为访问 FloatingActionButtons 数组,索引为 _currentPageIndex(由 bottomNavBar 和 _pageController 共享的私有变量。
这会突然更改 FAB,这不是所需的行为。
我正在尝试让 FAB 在页面发生变化(如 material spec:
时动画化(扩展和缩减)Tabbed Screens When tabs are present, the FAB should briefly disappear, then >reappear when the new content moves into place. This expresses >that the FAB is not connected to any particular tab.
对于如何简单地实施它的任何建议,我将不胜感激(我很确定我遗漏了一些微不足道的东西)。另一种方法是通过将 FAB 包裹在某种东西中来手动制作 FAB 的进出动画。
您可以尝试使用像这样的 AnimatedCrossFade
小部件:
class TestingNewWidgetState extends State<TestingNewWidget> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: AnimatedCrossFade(
crossFadeState: currentIndex == 0
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
firstChild: FloatingActionButton(
onPressed: () => null,
child: Icon(Icons.arrow_left),
backgroundColor: Colors.red,
),
secondChild: FloatingActionButton(
onPressed: () => null,
child: Icon(Icons.arrow_right),
backgroundColor: Colors.blue,
),
),
body: PageView(
onPageChanged: (index) {
setState(() {
currentIndex = index;
});
},
children: <Widget>[
Scaffold(
body: Center(
child: Text("page 1"),
),
),
Scaffold(
body: Center(
child: Text("page 2"),
),
),
],
),
);
}
}
更新
请记住,您可以创建自己的小部件,这是一个使用自定义 FloatingActionButton
的示例:
class TestingNewWidgetState extends State<TestingNewWidget> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
var customFabButton;
if (currentIndex == 0) {
customFabButton = CustomFabButton(
color: Colors.red,
onPressed: () => null,
icon: Icons.alarm,
);
} else if (currentIndex == 1) {
customFabButton = CustomFabButton(
color: Colors.blue,
onPressed: () => null,
icon: Icons.satellite,
);
} else {
customFabButton = CustomFabButton(
color: Colors.green,
onPressed: () => null,
icon: Icons.verified_user,
);
}
return Scaffold(
floatingActionButton: customFabButton,
body: PageView(
onPageChanged: (index) {
setState(() {
currentIndex = index;
});
},
children: <Widget>[
Scaffold(
body: Center(
child: Text("page 1"),
),
),
Scaffold(
body: Center(
child: Text("page 2"),
),
),
Scaffold(
body: Center(
child: Text("page 3"),
),
),
],
),
);
}
}
class CustomFabButton extends StatelessWidget {
final IconData icon;
final Color color;
final VoidCallback onPressed;
const CustomFabButton({Key key, this.icon, this.color, this.onPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: AnimatedContainer(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color,
),
duration: Duration(seconds: 1),
height: 50.0,
width: 50.0,
child: Icon(icon),
),
);
}
}