flutterdartflutter-navigationflutter-routes

Passing multiple arguments to named routes with flutter


I am trying to use named routes with multiple named arguments as the example below , and the problem is if I want to pass more than one argument to a screen so I need to define a custom class with these arguments . let's say I have 10 screens to navigate so it makes sense to define 10 custom classes with it's arguments ?

    import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateRoute: (settings) {
        if (settings.name == FirstScreen.routeName) {
        
          final args = settings.arguments as FirstScreenArguments;

          return MaterialPageRoute(
            builder: (context) {
              return FirstScreen(
                title: args.title,
                message: args.message,
              );
            },
          );
        } else if (settings.name == HomeScreen.routeName)
          return MaterialPageRoute(
            builder: (context) {
              return HomeScreen();
            },
          );
        assert(false, 'Need to implement ${settings.name}');
        return null;
      },
      title: 'Navigation with named arguments',
      initialRoute: HomeScreen.routeName,
    );
  }
}

class HomeScreen extends StatelessWidget {
  HomeScreen({Key? key}) : super(key: key);

  static const routeName = '/';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(
              context,
              FirstScreen.routeName,
              arguments: FirstScreenArguments(
                title: 'Welcome',
                message: "Coming from home screen ",
              ),
            );
          },
          child: const Text('Navigate to first screen'),
        ),
      ),
    );
  }
}

class FirstScreen extends StatelessWidget {
  final String title;
  final String message;

  const FirstScreen({Key? key, required this.title, required this.message})
      : super(key: key);

  static const routeName = '/firstScreen';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(title),
            Text(message),
          ],
        ),
      ),
    );
  }
}

class FirstScreenArguments {
  final String title;
  final String message;

  FirstScreenArguments({required this.title, required this.message});
}

Solution

  • The standard way is to define related class for each page, however you can create a JSON string on each page and pass it to another. for example, first define it in page 1:

    String temp = json.encode({
    par1:"test",
    par2:"test2" // and so on
    });
    

    then pass it to another page:

    Navigator.pushNamed(
                  context,
                  FirstScreen.routeName,
                  arguments: temp
                );
    

    then decode it on another page:

    Map<String, dynamic> data = json.decode(temp);