Flutter transition like iOS 13模态全屏
Flutter transition like iOS 13 modal full screen
我想要 iOS-Modal-Transition,新屏幕从底部开始动画,旧屏幕被推到后面。我发现了这个非常有前途的软件包:
这是我用来显示模态的函数:
showCupertinoModalBottomSheet(
expand: true,
context: context,
builder: (context) => Container(
color: AppColors.blue,
),
);
然而,这并不能 100% 正确地工作,因为后面的视图没有被推到后面。
我在这里错过了什么?如果有任何不清楚的地方,请告诉我!
这是我的更多代码:
这是我的整个页面,我希望从那里进行过渡:
class _MonthPageState extends State<MonthPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.secondary,
body: SafeArea(
child: Stack(
children: [
...
Positioned(
bottom: 10,
right: 20,
child: Hero(
tag: widget.month.name + 'icon',
child: AddButton(
onTapped: () {
showCupertinoModalBottomSheet(
expand: true,
context: context,
builder: (context) => Container(
color: AppColors.blue,
),
);
},
),
),
),
],
),
),
);
}
这是我的路由器:
class AppRouter {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialWithModalsPageRoute(
builder: (context) => HomePage(),
);
case '/month':
final Month month = settings.arguments as Month;
return _buildTransitionToMonthPage(month);
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}'),
),
),
);
}
}
static PageRouteBuilder _buildTransitionToMonthPage(Month month) {
return PageRouteBuilder(
transitionDuration: Duration(milliseconds: 450),
reverseTransitionDuration: Duration(milliseconds: 450),
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return MonthPage(
month: month,
);
},
transitionsBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return FadeTransition(opacity: animation, child: child);
},
);
}
}
为了获得推动动画,您需要将 CupertinoScaffold
与 CupertinoPageScaffold
一起使用,例如
@override
Widget build(BuildContext context) {
return CupertinoScaffold(
transitionBackgroundColor: Colors.white,
body: Builder(
builder: (context) => CupertinoPageScaffold(
backgroundColor: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: ElevatedButton(
child: Text('show modal'),
onPressed: () =>
CupertinoScaffold.showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.white,
builder: (context) => Container(
color: Colors.white,
child: Center(
child: ElevatedButton(
onPressed: () => Navigator.of(context)
.popUntil((route) =>
route.settings.name == '/'),
child: Text('return home'),
),
)),
)),
),
],
),
),
),
);
}
我想要 iOS-Modal-Transition,新屏幕从底部开始动画,旧屏幕被推到后面。我发现了这个非常有前途的软件包:
这是我用来显示模态的函数:
showCupertinoModalBottomSheet(
expand: true,
context: context,
builder: (context) => Container(
color: AppColors.blue,
),
);
然而,这并不能 100% 正确地工作,因为后面的视图没有被推到后面。
我在这里错过了什么?如果有任何不清楚的地方,请告诉我!
这是我的更多代码:
这是我的整个页面,我希望从那里进行过渡:
class _MonthPageState extends State<MonthPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.secondary,
body: SafeArea(
child: Stack(
children: [
...
Positioned(
bottom: 10,
right: 20,
child: Hero(
tag: widget.month.name + 'icon',
child: AddButton(
onTapped: () {
showCupertinoModalBottomSheet(
expand: true,
context: context,
builder: (context) => Container(
color: AppColors.blue,
),
);
},
),
),
),
],
),
),
);
}
这是我的路由器:
class AppRouter {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialWithModalsPageRoute(
builder: (context) => HomePage(),
);
case '/month':
final Month month = settings.arguments as Month;
return _buildTransitionToMonthPage(month);
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}'),
),
),
);
}
}
static PageRouteBuilder _buildTransitionToMonthPage(Month month) {
return PageRouteBuilder(
transitionDuration: Duration(milliseconds: 450),
reverseTransitionDuration: Duration(milliseconds: 450),
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return MonthPage(
month: month,
);
},
transitionsBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return FadeTransition(opacity: animation, child: child);
},
);
}
}
为了获得推动动画,您需要将 CupertinoScaffold
与 CupertinoPageScaffold
一起使用,例如
@override
Widget build(BuildContext context) {
return CupertinoScaffold(
transitionBackgroundColor: Colors.white,
body: Builder(
builder: (context) => CupertinoPageScaffold(
backgroundColor: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: ElevatedButton(
child: Text('show modal'),
onPressed: () =>
CupertinoScaffold.showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.white,
builder: (context) => Container(
color: Colors.white,
child: Center(
child: ElevatedButton(
onPressed: () => Navigator.of(context)
.popUntil((route) =>
route.settings.name == '/'),
child: Text('return home'),
),
)),
)),
),
],
),
),
),
);
}