在没有动画的情况下替换 MaterialApp 中的初始路线?
Replace initial Route in MaterialApp without animation?
我们的应用程序建立在 Scaffold
之上,到目前为止,我们已经能够使用 NavigatorState
中提供的调用满足我们的大部分路由和导航要求(pushNamed()
, pushReplacementNamed()
, 等等)。但是,我们不想要的是当用户从我们的抽屉(导航)菜单中选择一个项目时出现任何类型的 'push' 动画。我们希望导航菜单点击的目标屏幕有效地成为堆栈的新初始路由。目前我们为此使用 pushReplacementNamed() 以确保应用栏中没有后退箭头。但是,从右侧滑入的动画意味着堆栈正在构建。
在没有动画的情况下更改初始路线的最佳选择是什么?我们能否同时关闭抽屉动画?或者我们是否正在考虑一种情况,我们需要从 Navigator 转移到仅使用单个脚手架并在用户想要更改屏幕时直接更新 'body'?
我们注意到 NavigatorState
上有一个 replace()
调用,我们认为这可能是开始寻找的正确位置,但不清楚如何访问我们最初在 [=16 中设置的各种路由=].像 replaceNamed()
这样的东西可能是有序的 ;-)
你所做的听起来有点像 BottomNavigationBar
,所以你可能想考虑其中之一而不是 Drawer
。
但是,拥有一个 Scaffold
并在用户点击抽屉项目时更新 body
是一种完全合理的方法。您可能会考虑将 FadeTransition
从一个 body 更改为另一个
或者,如果您喜欢使用 Navigator
但不想要默认的幻灯片动画,您可以通过扩展 MaterialPageRoute
来自定义(或禁用)动画。这是一个例子:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyCustomRoute<T> extends MaterialPageRoute<T> {
MyCustomRoute({ WidgetBuilder builder, RouteSettings settings })
: super(builder: builder, settings: settings);
@override
Widget buildTransitions(BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
// Fades between routes. (If you don't want any animation,
// just return child.)
return new FadeTransition(opacity: animation, child: child);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Navigation example',
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/': return new MyCustomRoute(
builder: (_) => new MyHomePage(),
settings: settings,
);
case '/somewhere': return new MyCustomRoute(
builder: (_) => new Somewhere(),
settings: settings,
);
}
assert(false);
}
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Navigation example'),
),
drawer: new Drawer(
child: new ListView(
children: <Widget> [
new DrawerHeader(
child: new Container(
child: const Text('This is a header'),
),
),
new ListTile(
leading: const Icon(Icons.navigate_next),
title: const Text('Navigate somewhere'),
onTap: () {
Navigator.pushNamed(context, '/somewhere');
},
),
],
),
),
body: new Center(
child: new Text(
'This is a home page.',
),
),
);
}
}
class Somewhere extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Text(
'Congrats, you did it.',
),
),
appBar: new AppBar(
title: new Text('Somewhere'),
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new DrawerHeader(
child: new Container(
child: const Text('This is a header'),
),
),
],
),
),
);
}
}
像这样使用PageRouteBuilder
:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => Screen2(),
transitionDuration: Duration(seconds: 0),
),
);
如果你想要过渡,只需将下面的 属性 添加到上面的 PageRouteBuilder
,然后将 seconds
更改为 1
。
transitionsBuilder: (_, anim, __, child) => FadeTransition(opacity: anim, child: child),
要在显示路线时阻止动画,请将 RouteSettings(isInitialRoute: true)
传递给 PageRoute
构造函数。
参见this answer with working example and screen recording。
我们的应用程序建立在 Scaffold
之上,到目前为止,我们已经能够使用 NavigatorState
中提供的调用满足我们的大部分路由和导航要求(pushNamed()
, pushReplacementNamed()
, 等等)。但是,我们不想要的是当用户从我们的抽屉(导航)菜单中选择一个项目时出现任何类型的 'push' 动画。我们希望导航菜单点击的目标屏幕有效地成为堆栈的新初始路由。目前我们为此使用 pushReplacementNamed() 以确保应用栏中没有后退箭头。但是,从右侧滑入的动画意味着堆栈正在构建。
在没有动画的情况下更改初始路线的最佳选择是什么?我们能否同时关闭抽屉动画?或者我们是否正在考虑一种情况,我们需要从 Navigator 转移到仅使用单个脚手架并在用户想要更改屏幕时直接更新 'body'?
我们注意到 NavigatorState
上有一个 replace()
调用,我们认为这可能是开始寻找的正确位置,但不清楚如何访问我们最初在 [=16 中设置的各种路由=].像 replaceNamed()
这样的东西可能是有序的 ;-)
你所做的听起来有点像 BottomNavigationBar
,所以你可能想考虑其中之一而不是 Drawer
。
但是,拥有一个 Scaffold
并在用户点击抽屉项目时更新 body
是一种完全合理的方法。您可能会考虑将 FadeTransition
从一个 body 更改为另一个
或者,如果您喜欢使用 Navigator
但不想要默认的幻灯片动画,您可以通过扩展 MaterialPageRoute
来自定义(或禁用)动画。这是一个例子:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyCustomRoute<T> extends MaterialPageRoute<T> {
MyCustomRoute({ WidgetBuilder builder, RouteSettings settings })
: super(builder: builder, settings: settings);
@override
Widget buildTransitions(BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
// Fades between routes. (If you don't want any animation,
// just return child.)
return new FadeTransition(opacity: animation, child: child);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Navigation example',
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/': return new MyCustomRoute(
builder: (_) => new MyHomePage(),
settings: settings,
);
case '/somewhere': return new MyCustomRoute(
builder: (_) => new Somewhere(),
settings: settings,
);
}
assert(false);
}
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Navigation example'),
),
drawer: new Drawer(
child: new ListView(
children: <Widget> [
new DrawerHeader(
child: new Container(
child: const Text('This is a header'),
),
),
new ListTile(
leading: const Icon(Icons.navigate_next),
title: const Text('Navigate somewhere'),
onTap: () {
Navigator.pushNamed(context, '/somewhere');
},
),
],
),
),
body: new Center(
child: new Text(
'This is a home page.',
),
),
);
}
}
class Somewhere extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Text(
'Congrats, you did it.',
),
),
appBar: new AppBar(
title: new Text('Somewhere'),
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new DrawerHeader(
child: new Container(
child: const Text('This is a header'),
),
),
],
),
),
);
}
}
像这样使用PageRouteBuilder
:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => Screen2(),
transitionDuration: Duration(seconds: 0),
),
);
如果你想要过渡,只需将下面的 属性 添加到上面的 PageRouteBuilder
,然后将 seconds
更改为 1
。
transitionsBuilder: (_, anim, __, child) => FadeTransition(opacity: anim, child: child),
要在显示路线时阻止动画,请将 RouteSettings(isInitialRoute: true)
传递给 PageRoute
构造函数。
参见this answer with working example and screen recording。