背景
Flutter提供了两种不同的导航选项。
选项1.在MaterialPageRoute中使用Widget类。
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
);
}
}
class SecondRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
关键部分。
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
使用Navigator push方法,并将SecondRoute实例传递给MaterialPageRoute建设者。
如果需要通过参数。
class FirstRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open route'),
onPressed: () {
Navigator.push(
context,
// The parameter passed via SecondRoute constructor.
MaterialPageRoute(builder: (context) => SecondRoute(message: 'The message for second view.')),
);
},
),
),
);
}
}
class SecondRoute extends StatelessWidget {
// This is the parameter the SecondRoute needs.
final String message;
SecondRoute({@required this.message});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
选项2。使用路线。
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: RaisedButton(
child: Text('Launch screen'),
onPressed: () {
// Navigate to the second screen using a named route.
Navigator.pushNamed(context, '/second');
},
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
关键部分。
Navigator.pushNamed(context, '/second');
还需要在MaterialApp中注册路线。
void main() {
runApp(MaterialApp(
title: 'Named Routes Demo',
// Start the app with the "/" named route. In our case, the app will start
// on the FirstScreen Widget
initialRoute: '/',
routes: {
// When we navigate to the "/" route, build the FirstScreen Widget
'/': (context) => FirstScreen(),
// When we navigate to the "/second" route, build the SecondScreen Widget
'/second': (context) => SecondScreen(),
},
));
}
如果需要通过参数。
// When the user taps the button, navigate to a named route
// and provide the arguments as an optional parameter.
Navigator.pushNamed(
context,
'/second',
arguments: 'The message for second view.',
);
需要做一些额外的工作来获取参数。
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Gets the parameter from the route. Any type of the parameter is allowed.
final String message = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to the first screen by popping the current route
// off the stack
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
两个选项
问题
官方参考
答案 0 :(得分:0)
我认为不应该同时使用其中之一,为什么不能同时使用两者,但这取决于项目结构和产品要求。
我通常执行以下操作:
如果新屏幕取决于某些参数,任何参数,我将使用您的第一个选项,我非常喜欢在其构造函数(在本例中为小部件构造函数)中指定类的依赖关系。 / p>
如果我已经有了一个具有依赖性的屏幕,那么我不会将命名路由与“未命名”路由混合使用。
对于特殊的屏幕(例如选项卡导航中的根屏幕),它具有简单的导航(例如,关于我们的帮助,条款和条件),我通常会使用命名路线导航。
我认为,如果屏幕具有依赖项,那么您的第一个选择会更可靠,可以避免很多错误,并且可以进行类型检查,并且我认为它更易于扩展和维护。
第二个选项是用于简单导航。
因此,总而言之,我认为,如果框架提供了多种方法来做一件事情,那么您就不应该选择“ this AND the other”,通常最好选择“ this AND the another”,您应该考虑通常情况下,一种方法效果更好,而如果您发现另一种实现效果更好的情况,则不要害怕使用它。