0

I have MyApp class which is responsible for loading application. I'm loading a Class HomeWidget as home in MyApp.

void main() => runApp(new myApp());
class myApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
           return new MaterialApp(
             title: 'My App',
             color: Colors.grey,
             home: new HomeWidget(),
             theme: new ThemeData(
               primarySwatch: Colors.lightBlue,
             ),
             routes: <String, WidgetBuilder>{
                 "/ItemDetailWidget": (BuildContext context) => new MovieDetailsPage(),
    },
);}}

HomeWidget contains - Header, ListView, BottomNavigation.

When user taps particular item from ListView, I wanted to show new Widget/Page(ItemDetailWidget) which has all information about that particular item.

So i created ItemDetailWidget which is stateful and it accepts one parameter which is of type Object MyModel suppose. I made it stateful for purpose.

How should i add ItemDetailWidget into Routes as i'm passing parameter to it?

I tried using

        "/ItemDetailWidget": (BuildContext context) => new ItemDetailWidget(),

However, It throwing error as "The Constructor return type dynamic that isn't of expected type widget"

& Also how can i pass MyModel object to ItemDetailWidget using Navigator syntax? I'm having onTap() function in ListView.

Navigator.of(context).pushNamed('/widget1');

Tushar Pol
  • 7,119
  • 14
  • 29
  • 36

1 Answers1

1

This depends on the data you're sending; it sounds like in your case you have a bunch of movie details in a DB (or something), and you want to be able to show details for that movie. What you can do is use a unique identifier for each movie, and put that in the request; this is described more or less in the potential duplicate mentioned in the comments. The flutter stocks example also explains this.

To summarize:

  1. When you push, do a pushNamed("moviedetails/${movieUniqueIdentifier}").

  2. In your MaterialApp, you can set

routes:

routes: <String, WidgetBuilder>{
     '/':         (BuildContext context) => new Movie(movies, _configuration),
     '/settings': (BuildContext context) => new MovieSettings(_configuration)
  },

and:

onGenerateRoute: (routeSettings) {
  if (routeSettings.name.startsWith("movie:") {
     // parse out movie, get data, etc
  }
}

However, this isn't always the easiest way of doing things - say for example your database takes a while to respond and so you want to do a query before and then pass in the result (caching would be a good answer to this but let's ignore that for now =D). I'd still recommend the first method, but there are cases where it doesn't work.

To instead pass an object directly in (as the question actually asks) you can use:

Navigator.of(context).push(new PageRouteBuilder(pageBuilder: 
  (context, animation, secondaryAnimation) {
  // directly construct the your widget here with whatever object you want
  // to pass in.
})

Note that this will get quite messy if you have these Navigator.of(context).push blocks all over your code; I got away from this by using static convenience methods to it such as MyNavigator.pushMovie(context, movieObject) which would call Navigator.of(context).... under the hood. (I also subclass Navigator and so do MyNavigator.of(context) instead, but my setup is complicated as it does a bunch of additional custom navigation stuff).

rmtmckenzie
  • 37,718
  • 9
  • 112
  • 99