Ravgeet Dhillon
Ravgeet Dhillon

Reputation: 590

How to pass multiple arguments in named route in flutter

I am trying to pass multiple arguments to a named route. I have tried multiple things but have not succeeded so far. Can anyone tell me how to achieve this?

routes.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:brandcare/views/pdf_view.dart';
import 'package:brandcare/views/reports_view.dart';

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    final args = settings.arguments;
    switch (settings.name) {
      case 'reports':
        return CupertinoPageRoute(builder: (BuildContext context) => ReportsView());
      case 'pdf':
        return CupertinoPageRoute(builder: (BuildContext context) => PDFView());
      default:
        return CupertinoPageRoute(builder: (BuildContext context) => DashboardView());
    }
  }
}

Ontap event on a listitem in reports_view.dart

onTap: () {
  Navigator.pushNamed(
    context, 'pdf',
    arguments: PDFView(
      reportTitle: 'January Report',
      reportFullPath: 'https://static.example.com/reports/123456.pdf'
    )
  );
},

The page where I want to access multiple arguments

pdf_view.dart

class PDFView extends StatefulWidget {
  final String reportTitle;
  final String reportFullPath;

  PDFView({
    Key key,
    this.reportTitle,
    this.reportFullPath,
  }) : super(key: key);

  @override
  _PDFViewState createState() => _PDFViewState();
}

class _PDFViewState extends State<PDFView> {
  String title = this.widget.reporTitle;
  String url = this.widget.reportFullPath;
}

Upvotes: 17

Views: 33340

Answers (4)

Devendra
Devendra

Reputation: 3444

I prefer this way

Send

Navigator.pushNamed(context, "/secondpage", arguments: {'index': 5, 'title': "App title"});

Get & Forward

 case "/secondpage":
 final args = settings.arguments as Map<String, dynamic>;
 return MaterialPageRoute(builder: (_) => SecondPage(args));

Receive

print("index: ${widget.args['index']}");
print("title: ${widget.args['title']}");

Upvotes: 0

Anish Vahora
Anish Vahora

Reputation: 203

you can create your argument class in the target Widget Screen and pass its object as an argument from the source class.

Example:

// above will be the code for your target screen/widget as usual below will be the respected argument class for the same target screen/widget

    class WeatherRouteArguments {
      WeatherRouteArguments({ required this.city, required this.country });
      final String city;
      final String country;
    
      bool get isGermanCapital {
        return country == 'Germany' && city == 'Berlin';
      }
    }

invoking the screen with argument you can do as below:

void _showWeather() {
  Navigator.pushNamed(
    context,
    '/weather',
    arguments: WeatherRouteArguments(city: 'Berlin', country: 'Germany'),
  );
}

I guess you know how to get the argument in the build of target widget class, it can be done as below:

 final args = ModalRoute.of(context)!.settings.arguments as WeatherRouteArguments;

refrence : https://api.flutter.dev/flutter/widgets/Navigator/pushNamed.html

Upvotes: 7

marre
marre

Reputation: 769

I achieved it by passing in a list of the different arguments like this:

Navigator.of(context).pushNamed("/someRoute", arguments:[8, "a string"]);

And then in the route generator i forward them like this:

// ...    
case "/someRoute":
  List<dynamic> args = settings.arguments;;
  return MaterialPageRoute(builder: (_) => SomeScreen(someInt: args[0], someString: args[1])); 

Upvotes: 28

harpreet seera
harpreet seera

Reputation: 1828

You are passing the wrong argument. You need to pass a specific argument object which you want. For your case you need to create one like this:

class ScreenArguments {
  final String reportTitle;
  final String reportFullPath;

  ScreenArguments(this.reportTitle, this.reportFullPath);
}

Now pass this object as argument while pushing a route like this:

Navigator.pushNamed(
      context,
      'pdf',
      arguments: ScreenArguments(
        'January Report',
         'https://static.example.com/reports/123456.pdf',
      ),
    );

Now you need to access the arguments passed to the route in route generator. Just like this:

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    final args = settings.arguments;
    switch (settings.name) {
      case 'reports':
        return CupertinoPageRoute(builder: (BuildContext context) => ReportsView());
      case 'pdf':
        return CupertinoPageRoute(builder: (BuildContext context) {
          ScreenArguments argument = args;
          return PDFView(
            reportTitle: argument.reportTitle,
            reportFullPath: argument.reportFullPath,
          );
        });
      default:
        return CupertinoPageRoute(builder: (BuildContext context) => DashboardView());
    }
  }
}

This would solve your problem

Upvotes: 38

Related Questions