我有很多屏幕,我正在使用Navigator.我想使用"命名路由",但我还需要将非字符串(如图像)传递给下一个路由.
我无法使用,pushNamed()因为我无法将非字符串数据传递给它.
如何使用命名路由+发送非字符串数据?
Rém*_*let 43
编辑:
现在可以将复杂的参数传递给Navigator.pushNamed:
String id;
Navigator.pushNamed(context, '/users', arguments: id);
Run Code Online (Sandbox Code Playgroud)
然后可以使用它来使用onGenerateRoute以下参数自定义路由构建:
MaterialApp(
title: 'Flutter Hooks Gallery',
onGenerateRoute: (settings) {
final arguments = settings.arguments;
switch (settings.name) {
case '/users':
if (arguments is String) {
// the details page for one specific user
return UserDetails(arguments);
}
else {
// a route showing the list of all users
return UserList();
}
default:
return null;
}
},
);
Run Code Online (Sandbox Code Playgroud)
San*_*ngh 26
通过使用地图
在推送参数时,您可以以地图形式推送参数,并且可以在提取它们时执行相同操作。
例如
推的同时
Navigator.of(context).pushNamed(
'second',
arguments: {
'title':'This is a String',
or
'Fx': This could be any widget or Function
}Run Code Online (Sandbox Code Playgroud)
在提取目标页面中的参数时
final routes=ModalRoute.of(context).settings.arguments as Map<String,String>;
return Scaffold(
appBar: AppBar(
title: Text(routes['title']),
),
body: Container(
child: Center(
child: RaisedButton(
child: Text("Back"),
onPressed: ()=>Navigator.of(context).pop(),
),
),
),
);
and choose your map accordingly accordinglyRun Code Online (Sandbox Code Playgroud)
这里有许多巨大的解决方案,但是您的问题可以使用此库通过两行字面来解决:https : //pub.dev/packages/get
List users = [2,4,6,3]
Get.toNamed('/second', arguments: users);
Run Code Online (Sandbox Code Playgroud)
在第二条路线上
print(Get.arguments);
// out: [2,4,6,3]
Run Code Online (Sandbox Code Playgroud)
与其他解决方案相比,使用它的优势在于你可以通过参数传递任何东西,如果你愿意,甚至可以传递类实例,并且你可以从任何地方检索参数,包括在你的 UI 中,在你的块、控制器、你的提供者等中,无需将 onGenerateRoute 中的参数传递给类。
使用onGenerateRoute很容易传递路线过渡复杂的参数Navigator.pushNamed或Navigator.pushReplacementNamed
展示概念的最小设置是
import 'package:flutter/material.dart';
import 'package:navigator/routes.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (BuildContext context) => makeRoute(
context: context,
routeName: settings.name,
arguments: settings.arguments,
),
maintainState: true,
fullscreenDialog: false,
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
在该_buildRoute方法中,我们检查路由名称,并将参数强制转换为必需的类型。
缺点是,如果必需的参数不是简单类型,则必须事先定义类型。
import 'package:flutter/material.dart';
import 'package:navigator/list.dart';
import 'package:navigator/details.dart';
Widget makeRoute(
{@required BuildContext context,
@required String routeName,
Object arguments}) {
final Widget child =
_buildRoute(context: context, routeName: routeName, arguments: arguments);
return child;
}
Widget _buildRoute({
@required BuildContext context,
@required String routeName,
Object arguments,
}) {
switch (routeName) {
case '/':
return ArticleList();
case '/ArticleView':
Article article = arguments as Article;
return ArticleView(article: article);
default:
throw 'Route $routeName is not defined';
}
}
Run Code Online (Sandbox Code Playgroud)
观看次数
Article在我们的例子中,使用定义的类型构造route参数。
import 'package:flutter/material.dart';
import 'package:navigator/details.dart' show Article;
class ArticleList extends StatefulWidget {
@override
_ArticleListState createState() => _ArticleListState();
}
class _ArticleListState extends State<ArticleList> {
List<Article> articles = [
Article(
id: 1,
title: 'Article 1',
author_name: 'Nilotpal',
summary: 'Article 1 summary'),
Article(
id: 2,
title: 'Article 2',
author_name: 'Mike',
summary: 'Article 2 summary'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Articles'),
),
body: Center(
child: Column(
children: <Widget>[
ListTile(
title: Text('${articles[0].title}'),
subtitle: Text('by ${articles[0].author_name}'),
onTap: () {
Navigator.of(context)
.pushNamed('/ArticleView', arguments: articles[0]);
},
),
ListTile(
title: Text('${articles[1].title}'),
subtitle: Text('by ${articles[1].author_name}'),
onTap: () {
Navigator.of(context)
.pushNamed('/ArticleView', arguments: articles[1]);
},
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
定义参数的类型
import 'package:flutter/material.dart';
class Article {
final int id;
final String author_name;
final String title;
final String summary;
Article(
{@required this.id,
@required this.author_name,
@required this.title,
@required this.summary});
}
class ArticleView extends StatelessWidget {
final Article _article;
ArticleView({@required Article article}) : _article = article;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${_article.title}'),
),
body: SafeArea(
top: true,
child: Center(
child: Column(
children: <Widget>[
Text('${_article.author_name}'),
Text('${_article.summary}'),
],
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用routesApp 的参数直接传递参数。
像这样:
routes: {
HomePage.route: (_) => HomePage(),
DetailsPage.route: (context) =>
DetailsPage(ModalRoute.of(context).settings.arguments),
},
Run Code Online (Sandbox Code Playgroud)
在这种情况下,完整的示例将如下所示:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: HomePage.route,
routes: {
HomePage.route: (_) => HomePage(),
DetailsPage.route: (context) =>
DetailsPage(ModalRoute.of(context).settings.arguments),
},
);
}
}
class HomePage extends StatelessWidget {
static const String route = '/';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/details',
arguments: ScreenArguments(
'My Details',
'Some Message',
));
},
),
);
}
}
class DetailsPage extends StatelessWidget {
static const String route = '/details';
final ScreenArguments arguments;
DetailsPage(this.arguments);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(arguments.title),
),
body: Center(
child: Text(arguments.message),
),
);
}
}
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11861 次 |
| 最近记录: |