How do I pass non-string data to a named route in

2019-01-09 00:08发布

问题:

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]),
        );
      },
    );
  }
}


标签: dart flutter