I want to pass data from 2nd Screen to 1st Screen in flutter

Issue

I am making a simple TODO app and I wanted to pass data from 2nd Screen of my app to 1st screen. My first Screen is initially blank and there is nothing to display and it has a floating button to add a task. When it is clicked it takes to the Second page where user inputs the task and author and Clicks on "Submit" Button and takes us to 1st page where it gets Displayed. I want to pass data as List .I am trying everything for last 24 hours I implemented using ModalRoute and also created one instance of ToDo class so that it doesn’t give NULL error but nothing is working out. I am attaching code So that you can understand my problem.

This is my FirstScreen()

import 'package:flutter/material.dart';
import 'todo.dart';
import 'todocard.dart';

class ToDos extends StatefulWidget{
 @override
 _ToDosState createState() => _ToDosState();
}

class _ToDosState extends State<ToDos> {

@override
Widget build(BuildContext context) {

List<ToDo> todos =[

];
final routeArgs = ModalRoute.of(context).settings.arguments as Map ;
todos.add(ToDo(author: routeArgs['task'],task: routeArgs['author']));

 return Container(
  child: Scaffold(
    appBar: AppBar(
      title: Text("TODO LIST"),
      centerTitle: true,
    ),
    body: Column(
      children:todos.map((e) => ToDoCard(
          todo: e,
      )).toList(),
      //ToDoCard is just a Card widget

    ),
    floatingActionButton: FloatingActionButton(
      elevation: 0.0,
      child: Text("+"),
      onPressed: ()
      {
        Navigator.pushNamed(context, '/add_task');
      },
    ),
  ),

);

}
}

My SecondScreen is :

import 'package:flutter/material.dart';

class AddTask extends StatefulWidget {
  @override
  _AddTaskState createState() => _AddTaskState();
}

class _AddTaskState extends State<AddTask> {
  @override
  Widget build(BuildContext context) {
    String author,task;
    return Container(
        child: Scaffold(
          appBar: AppBar(
            title: Text("ADD TASK"),
            centerTitle: true,
          ),
          body: Column(
            children: <Widget>[
              Text("Enter Your Task"),
              TextField(
                decoration: InputDecoration(
                    border: InputBorder.none,
                    hintText: 'task'
                ),
                onChanged: (text){
                  task = text;
                },
              ),

              TextField(
                decoration: InputDecoration(
                    border: InputBorder.none,
                    hintText: 'author'
                ),
                onChanged: (text){
                  author = text;
                },
              ),

              Row(
                children: <Widget>[
                  RaisedButton(
                    onPressed: () {
                      Navigator.pop(context, {
                        'author': author,
                        'task': task,
                      });
                    },
                    child: Text("Submit"),
                  ),
                  SizedBox(width: 10.0,),
                  RaisedButton(
                    onPressed: () {
                      Navigator.pop(context);
                    },
                    child: Text("Cancel"),
                  ),
                ],
              )

            ],
          ),
        ));
  }
}

The main.dart is as Follows:

import 'package:flutter/material.dart';
import 'todo.dart';
import 'add_task.dart';
import 'display_todo.dart';

void main() {
  runApp(MaterialApp(
    title: 'Passing Data',
    initialRoute: '/',
    routes: {
      '/': (context) => ToDos(),
      '/add_task': (context) => AddTask(),
    },
  ));
}

The ToDoCard for displaying the info as Card:

import 'todo.dart';
import 'package:flutter/material.dart';

class ToDoCard extends StatelessWidget {
  final ToDo todo;
  ToDoCard({this.todo});
  @override
  Widget build(BuildContext context) {
    return Card(
      color: Colors.cyan,
      margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
      child: Padding(
        padding: EdgeInsets.fromLTRB(13, 10, 13, 10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[

            Text(
              todo.author,
              style: TextStyle(
                color: Colors.black,
                fontSize: 20.0,
              ),
            ),
            SizedBox(height: 10.0,),
            Text(
              todo.task,
              style: TextStyle(
                color: Colors.black,
                fontSize: 20.0,
              ),
            ),
            SizedBox(height: 10.0,),
//            RaisedButton.icon(onPressed: delete, icon: Icon(Icons.delete), label: 
Text("Delete quote"), color: Colors.red,),

          ],
        ),
      ),
    );
  }
}

ToDo class:

class ToDo{
final String task;
final String author;
ToDo({this.task,this.author});
}

Solution

You can pass the result back on the Navigator.pop() and retrieve it by awaiting the pushNamed call.

Retrieve value in Page 1:

onPressed: () async
{
  dynamic result = await Navigator.pushNamed(context, '/add_task');
  if(result != null) {
    setState(() {todos.add(result);});
  }
},

Pass value from page 2 in the submit button

onPressed: () {
  Navigator.pop(context, ToDo(task: task, author: author));
},

Answered By – Christopher Moore

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *