可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using Flutter for my mobile app. I have many screens, and I'm using the Navigator. I'd like to use "named routes", but I also need to pass non-string (such as images) to my next route.
I can't use pushNamed()
because I can't pass non-string data to it.
How can I use a named route + send non-string data?
回答1:
A named route should by principle be self describing. You shouldn't try to do something like pushNamed("/myRoute", myObject)
. Instead, you should do something like pushNamed("myRoute/${myObject.id}")
and then extract that id from the route path, and use it to request the required data.
Which is where onGenerateRoute
available as a MaterialApp
property is used.
You could for example do something like this :
onGenerateRoute: (routeSettings) {
var path = routeSettings.name.split('/');
if (path[0] == "myRoute") {
final foo = path.length > 1 ? int.parse(path[1]) : null;
return new MaterialPageRoute(
builder: (context) => new MyPage(foo: foo),
settings: routeSettings,
);
}
// fallback route here
},
回答2:
For the outcome of this problem, I developed the package
link: https://pub.dartlang.org/packages/navigate
That provide to much your expect and easy to use
Navigate.navigate(context,
"home",
transactionType:TransactionType.fromLeft , // optional
replaceRoute: ReplaceRoute.thisOne, //optional
arg: {"transactionType":TransactionType.fromLeft,"replaceRoute":ReplaceRoute.thisOne} //optional
);
回答3:
I am capturing images with camera then passing them through to a confirmation page like so:
ImagePicker.pickImage(source: source).then((File file) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MediaCaptured(file: file),
));
});
You could easily do the same with any type of file or non-string data.
var foo = "non-string data";
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MediaCaptured(foo: foo),
));
Call the next page in the route by it's class name, as above.
Just make sure your new page accepts this in it's constructor.
// Stateful Widget
class MediaCaptured extends StatefulWidget {
MediaCaptured({ Key key, @required this.foo,}) : super(key: key);
final var foo;
}
// StatelessWidget
class MediaCaptured extends StatelessWidget {
MediaCaptured(this.foo);
var foo;
}
回答4:
The Flutter Cookbook shows how to navigate to a new page and pass non-string data to it.
Passing data to next page
I started with Navigator.pushedNamed()
because it was simple and I didn't have any data to pass. When my needs changed and I wanted to pass data, I switched to Navigator.push()
.
Example:
var nextPageData = {foo:'bar'};
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>
MyNextPage(myData: nextPageData))
);
回答5:
We can pass any type of arguments when declaring routes as constructor arguments as below,
For example to send a list of Strings,
List<String> titles = [];
void main() => runApp(
new MaterialApp(
home: new FirstPage(),
routes: <String, WidgetBuilder>{
"/SecondPage": (BuildContext context) => new SecondPage(titles),
},
),
);
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(
child: new RaisedButton(onPressed: () {
Navigator.of(context).pushNamed('/SecondPage');
}),
);
}
}
class SecondPage extends StatelessWidget {
final List<String> titles;
SecondPage(this.titles);
@override
Widget build(BuildContext context) {
return new ListView.builder(
itemBuilder: (context, index) {
return new ListTile(
title: new Text(titles[index]),
);
},
);
}
}