Navigation with pass data in flutter

In Flutter, passing data between screens is a common requirement when building mobile applications. Flutter provides several methods to accomplish this, including using constructors, named routes, and using a state management solution like Provider or GetX. In this web page description, we’ll explore a simple example of passing data between screens using constructors.

Passing data between screens is a common requirement in mobile app development. Flutter provides several ways to achieve this functionality. In this tutorial, we will explore three different methods for passing data between screens in Flutter, along with practical examples.


Method 1: Using Constructor

In this method, data is passed from one screen to another by passing it through the constructor of the destination screen. This approach is straightforward and suitable for passing small amounts of data.

 ElevatedButton(onPressed: (){
              Navigator.push(context, MaterialPageRoute(builder: (_)=>SecondScreen(name:name.text)));
            }, child: Text("Method 1")
)
Dart
class SecondScreen extends StatefulWidget{
String? name='';

  SecondScreen({this.name});

  @override
  State<StatefulWidget> createState()=>SecondScreenState();

}
Dart

Method 2 – Using Named Routes and Arguments

Without create route

This method involves defining named routes and passing arguments along with those routes. It provides better organization and flexibility for passing complex data structures.

Navigator.push(
                  context, MaterialPageRoute(builder: (_)=>SecondScreen(name:''),
                  settings:RouteSettings(
                    arguments: {
                      'name':name.text,
                      'type':2
                    })
              ),
              );
            }, child: Text("Method 2")
)
Dart
@override
  Widget build(BuildContext context) {
  var args=ModalRoute.of(context)!.settings.arguments==null{}:ModalRoute.of(context)!.settings.arguments as Map<String,dynamic>;
    
   return ..;
  }
Dart

With Create route

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      //naviagate as default screen
      initialRoute: "main",
      //this is a route of app
      routes: {
        "main":(BuildContext context)=>MyHomePage(),
        "second":(BuildContext context)=>SecondScreen(name: "",),
      },
      //if you use method 3 than comment this line
      // home: MyHomePage(),
    );
  }
}
Dart
ElevatedButton(onPressed: (){
              Navigator.pushNamed(
                  context,
                "second",
                  arguments: {
                    'name':name.text,
                    'type':3
                  }
              );
            }, child: Text("Method 3"))
Dart

Full code

import 'package:flutter/material.dart';
import 'package:navigation_in_flutter/SecondScreen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      //naviagate as default screen
      initialRoute: "main",
      //this is a route of app
      routes: {
        "main":(BuildContext context)=>MyHomePage(),
        "second":(BuildContext context)=>SecondScreen(name: "",),
      },
      //if you use method 3 than comment this line
      // home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  TextEditingController name=TextEditingController();

  @override
  Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text("Navigation Demo"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              controller: name,
            ),
            SizedBox(height: 20,),
            ElevatedButton(onPressed: (){
              Navigator.push(context, MaterialPageRoute(builder: (_)=>SecondScreen(name:name.text)));
            }, child: Text("Method 1"))
            ,ElevatedButton(onPressed: (){
              Navigator.push(
                  context, MaterialPageRoute(builder: (_)=>SecondScreen(name:''),
                  settings:RouteSettings(
                    arguments: {
                      'name':name.text,
                      'type':2
                    })
              ),
              );
            }, child: Text("Method 2"))
            ,ElevatedButton(onPressed: (){
              Navigator.pushNamed(
                  context,
                "second",
                  arguments: {
                    'name':name.text,
                    'type':3
                  }
              );
            }, child: Text("Method 3"))
          ],
        ),
      ),
    );
  }

}
Dart
import 'package:flutter/material.dart';

class SecondScreen extends StatefulWidget{
  String? name='';

  SecondScreen({this.name});

  @override
  State<StatefulWidget> createState()=>SecondScreenState();

}

class SecondScreenState extends State<SecondScreen> {
  @override
  Widget build(BuildContext context) {
    var args= ModalRoute.of(context)!.settings.arguments==null?{}:ModalRoute.of(context)!.settings.arguments as Map<String,dynamic>;



    return Scaffold(
      appBar: AppBar(
        title: Text("Secod Screen"),
      ),
      body: Center(
        child:
        Column(
          children: [
            Divider(),
            Text("Method 1"),
            Text("${widget.name}"),
            Divider(),
            Divider(),
            Text("Method 2"),
            Text(args['type']==2?"${args['name']}":""),
            Divider(),
            Divider(),
            Text("Method 3"),
            Text(args['type']==3?"${args['name']}":""),
            Divider(),
          ],
        ),
      ),
    );
  }
}
Dart

Conclusion

In this tutorial, we explored three different methods for passing data between screens in Flutter. Each method offers its own benefits depending on the complexity and scope of your application. By using these techniques, you can create dynamic and interactive apps that seamlessly transfer data between screens.

Note: The provided examples assume basic familiarity with Flutter and assume that the necessary imports and dependencies have been properly configured.

Remember to customize the example code to suit your specific application requirements.