skip to Main Content

I am building a flutter app and passing data from addTaskScreen to the homeScreen using navigation. But when I am pressing the back button from homeScreen, the app is going to the previous state and shows previous un-updated data. How to prevent it.

Here is the code of my two screens,

home screen:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:todo/database/database.dart';
import 'package:todo/hidden_screen.dart';
import 'package:todo/models/task_model.dart';
// import 'package:sqflite/sqflite.dart';

import 'add_todo_screen.dart';

// ignore: use_key_in_widget_constructors
class HomeScreen extends StatefulWidget {
// const HomeScreen({super.key});

@override
State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
late Future<List<Task>> _taskList;

final DateFormat _dateFormatter = DateFormat('MMM dd, yyyy');

// ignore: unused_field
final DatabaseHelper _databaseHelper = DatabaseHelper.instance;

@override
void initState() {
  super.initState();
 _updateTaskList();
}

_updateTaskList() {
_taskList = DatabaseHelper.instance.getTaskList();
}

Widget _buildTask(Task task) {
 return Column(
  children: [
    ListTile(
      title: Text(
        task.title!,
        style: TextStyle(
          fontFamily: 'Mordred',
          color: task.status == 0 ? Colors.black87 : Colors.black12,
          decoration: task.status == 0
              ? TextDecoration.none
              : TextDecoration.lineThrough,
        ),
      ),
      subtitle: Text(
        '${_dateFormatter.format(task.date!)} - ${task.priority}',
        style: TextStyle(
          fontFamily: 'Mordred',
          color: task.status == 0 ? Colors.black87 : Colors.black12,
          decoration: task.status == 0
              ? TextDecoration.none
              : TextDecoration.lineThrough,
        ),
      ),
      trailing: Checkbox(
        checkColor: Colors.black,
        tristate: false,
        onChanged: (value) {
          // print(value);
          task.status = value! ? 1 : 0;
          DatabaseHelper.instance.updateTask(task);
          _updateTaskList();
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(
              builder: (_) => HomeScreen(),
            ),
          );
        },
        activeColor: Theme.of(context).primaryColor,
        value: task.status == 1 ? true : false,
      ),
      onTap: () => Navigator.push(
        context,
        CupertinoPageRoute(
          builder: (_) => AddToDoScreen(
            updateTaskList: _updateTaskList(),
            task: task,
          ),
        ),
      ),
    ),
    const Divider(
      height: 20,
      thickness: 20,
    )
  ],
);
}
@override
Widget build(BuildContext context) {
 return Scaffold(
  backgroundColor: Colors.lime[100],
  appBar: AppBar(
    leading: GestureDetector(
      onLongPress: () {
        Navigator.push(
          context,
          CupertinoPageRoute(
            builder: (_) => const HiddenScreen(),
          ),
        );
      },
      child: const Padding(
        padding: EdgeInsets.fromLTRB(10, 10, 0, 5),
        // child: Icon(
        //   Icons.tornado_rounded,
        //   color: Colors.lime[100],
        //   size: 30,
        // ),
        // child: Image.asset(
        //   'assets/images/box.gif',
        //   fit: BoxFit.cover,
        // ),
        child: CircleAvatar(
          backgroundImage: AssetImage(
            'assets/images/box.gif',
          ),
        ),
      ),
    ),
    title: const Text(
      'Things To Do',
      style: TextStyle(fontFamily: 'Binary X CHR', fontSize: 36),
    ),
    elevation: 60,
  ),
  floatingActionButton: FloatingActionButton(
    backgroundColor: Theme.of(context).primaryColor,
    onPressed: () {
      Navigator.push(
        context,
        CupertinoPageRoute(
          builder: (_) => AddToDoScreen(
            updateTaskList: _updateTaskList,
          ),
        ),
      );
    },
    child: const Icon(Icons.ac_unit_rounded),
  ),
  body: FutureBuilder(
    future: _taskList,
    builder: (context, AsyncSnapshot snapshot) {
      if (!snapshot.hasData) {
        return const Center(
          child: CircularProgressIndicator(),
        );
      }

      final int completedTaskCount = snapshot.data!
          .where((Task task) => task.status == 1)
          .toList()
          .length;

      return ListView.builder(
        padding: const EdgeInsets.symmetric(vertical: 20.0),
        itemCount: int.parse(snapshot.data!.length.toString()) + 1,
        itemBuilder: (BuildContext conntext, int index) {
          if (index == 0) {
            return Padding(
              padding: const EdgeInsets.symmetric(
                horizontal: 40,
                vertical: 30,
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  const Text(
                    'MY TASK',
                    style: TextStyle(
                      color: Colors.black38,
                      fontFamily: 'Binary X CHR',
                      fontSize: 40,
                      // fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  Text(
                    '$completedTaskCount out of ${snapshot.data.length} Completed',
                    style: const TextStyle(
                      color: Colors.black38,
                      fontFamily: 'Binary X CHR',
                      fontSize: 20,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ],
              ),
            );
          }
          return _buildTask(snapshot.data![index - 1]);
        },
      );
     },
    ),
   );
  }
}

add task screen:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:todo/database/database.dart';
import 'package:todo/home_screen.dart';

import 'models/task_model.dart';

class AddToDoScreen extends StatefulWidget {
// const AddToDoScreen({super.key});
final Task? task;
final Function? updateTaskList;

const AddToDoScreen({super.key, this.task, this.updateTaskList});

@override
State<AddToDoScreen> createState() => _AddToDoScreenState(); 
}

class _AddToDoScreenState extends State<AddToDoScreen> {
final _formKey = GlobalKey<FormState>();

String _title = '';
String _priority = 'Low';

DateTime _date = DateTime.now();

String btnText = "Add Task";
String titleText = "Add Title";

final TextEditingController _dateController = TextEditingController();

final DateFormat _dateFormatter = DateFormat('MMM dd, yyyy');
final List<String> _priorities = ['Low', 'Medium', 'High'];

@override
void initState() {
  super.initState();

if (widget.task != null) {
  _title = widget.task!.title!;
  _date = widget.task!.date!;
  _priority = widget.task!.priority!;

  setState(() {
    btnText = "Update Task";
    titleText = "Update Task";
  });
} else {
  setState(() {
    btnText = "Add Task";
    titleText = "Add Task";
  });
}
_dateController.text = _dateFormatter.format(_date);
}

@override
void dispose() {
_dateController.dispose();
super.dispose();
}

_handleDatePicker() async {
final DateTime? date = await showDatePicker(
  context: context,
  initialDate: _date,
  firstDate: DateTime(1900),
  lastDate: DateTime(2100),
);
if (date != null && date != _date) {
  setState(() {
    _date = date;
  });
  _dateController.text = _dateFormatter.format(date);
 }
}

_delete() {
 DatabaseHelper.instance.deleteTask(widget.task!.id!);
Navigator.pushReplacement(
  context,
  MaterialPageRoute(
    builder: (_) => HomeScreen(),
  ),
);
widget.updateTaskList!();
}

_submit() {
if (_formKey.currentState!.validate()) {
  _formKey.currentState!.save();

  // print to check if the data is saving to database or not
  // print('$_title, $_date, $_priority');

  Task task = Task(title: _title, date: _date, priority: _priority);

  if (widget.task == null) {
    task.status = 0;
    DatabaseHelper.instance.insertTask(task);

    Navigator.pushReplacement(
      context,
      MaterialPageRoute(
        builder: (_) => HomeScreen(),
      ),
    );
  } else {
    task.id = widget.task!.id;
    task.status = widget.task!.status;
    DatabaseHelper.instance.updateTask(task);

    Navigator.pushReplacement(
      context,
      MaterialPageRoute(
        builder: (_) => HomeScreen(),
      ),
    );
    Navigator.pop(
      context,
      MaterialPageRoute(
        builder: (_) => HomeScreen(),
      ),
    );
  }
   widget.updateTaskList!();
 }
}

@override
Widget build(BuildContext context) {
return Scaffold(
  backgroundColor: Colors.lime[100],
  body: GestureDetector(
    onTap: () => FocusScope.of(context).unfocus(),
    child: SingleChildScrollView(
      child: Container(
        padding:
            const EdgeInsets.symmetric(horizontal: 30.0, vertical: 50.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            GestureDetector(
              onTap: () => Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (_) => HomeScreen(),
                ),
              ),
              child: Icon(
                Icons.arrow_back_ios_new_rounded,
                size: 30.0,
                color: Theme.of(context).primaryColor,
              ),
            ),
            const SizedBox(
              height: 20.0,
            ),
            Text(
              titleText,
              style: const TextStyle(
                fontSize: 40,
                fontFamily: 'Mordred',
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(
              height: 10,
            ),
            Form(
              key: _formKey,
              child: Column(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(
                      vertical: 20.0,
                    ),
                    child: TextFormField(
                      style: const TextStyle(
                        fontSize: 18.0,
                        fontFamily: 'Mordred',
                      ),
                      decoration: InputDecoration(
                        labelText: 'Title',
                        labelStyle: const TextStyle(
                          // color: Colors.black,
                          fontSize: 18,
                          fontFamily: 'Mordred',
                        ),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10.0),
                        ),
                      ),
                      validator: (input) => input!.trim().isEmpty
                          ? 'Please enter a task title'
                          : null,
                      onSaved: (input) => _title = input!,
                      initialValue: _title,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(
                      vertical: 20.0,
                    ),
                    child: TextFormField(
                      readOnly: true,
                      controller: _dateController,
                      onTap: _handleDatePicker,
                      style: const TextStyle(
                        fontSize: 18.0,
                        fontFamily: 'Mordred',
                      ),
                      decoration: InputDecoration(
                        labelText: 'Date',
                        labelStyle: const TextStyle(
                          fontSize: 18,
                          fontFamily: 'Mordred',
                        ),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10.0),
                        ),
                      ),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 20),
                    child: DropdownButtonFormField(
                      isDense: true,
                      icon: const Icon(Icons.double_arrow_rounded),
                      iconSize: 20,
                      iconEnabledColor: Theme.of(context).primaryColor,
                      iconDisabledColor: Colors.black54,
                      items: _priorities.map((String priority) {
                        return DropdownMenuItem(
                          value: priority,
                          child: Text(
                            priority,
                            style: const TextStyle(
                                color: Colors.black54,
                                fontSize: 18,
                                fontFamily: 'Mordred'),
                          ),
                        );
                      }).toList(),
                      style: const TextStyle(fontSize: 18),
                      decoration: InputDecoration(
                        labelText: 'Priority',
                        labelStyle: const TextStyle(
                          fontSize: 18,
                          fontFamily: 'Mordred',
                        ),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      value: _priority,
                      // ignore: unnecessary_null_comparison
                      validator: (input) => _priority == null
                          ? 'Please select a priority level'
                          : null,
                      onChanged: (value) {
                        setState(
                          () {
                            _priority = value.toString();
                          },
                        );
                      },
                    ),
                  ),
                  Container(
                    margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                    height: 60.0,
                    width: double.infinity,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(30),
                    ),
                    child: ElevatedButton(
                      style: ButtonStyle(
                        backgroundColor:
                            MaterialStateProperty.all(Colors.lime),
                      ),
                      onPressed: _submit,
                      child: Text(
                        btnText,
                        style: TextStyle(
                          color: Colors.lime[100],
                          fontSize: 20,
                          fontFamily: 'Mordred',
                        ),
                      ),
                    ),
                  ),
                  widget.task != null
                      ? Container(
                          margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
                          height: 60.0,
                          width: double.infinity,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(30),
                          ),
                          child: ElevatedButton(
                            style: ButtonStyle(
                              backgroundColor:
                                  MaterialStateProperty.all(Colors.lime),
                            ),
                            onPressed: _delete,
                            child: Text(
                              'Delete Task',
                              style: TextStyle(
                                color: Colors.lime[100],
                                fontSize: 20,
                                fontFamily: 'Mordred',
                              ),
                            ),
                          ),
                        )
                      : const SizedBox.shrink(),
                ],
              ),
            ),
          ],
        ),
      ),
    ),
   ),
  );
 }
}

3

Answers


  1. Chosen as BEST ANSWER

    Thanks, everyone for the answers. And I have found the solution and it helped me to solve the problem. I have just used pushAndRemoveUntil instead of pushReplacement.

    Here is my code with problem part:

    // onTap: () => Navigator.pushReplacement(
                  //   context,
                  //   MaterialPageRoute(
                  //     builder: (_) => HomeScreen(),
                  //   ),
                  // ),
    

    And here is the solution:

    onTap: () => Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(
                      builder: (context) => HomeScreen(),
                    ),
                    (Route<dynamic> route) => false,
                  ),
    

  2. You have the following section in your code:

        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (_) => HomeScreen(),
          ),
        );
        Navigator.pop(
          context,
          MaterialPageRoute(
            builder: (_) => HomeScreen(),
          ),
        );
    

    This might make it go to the home screen and then pop to a previous state again?

    Maybe take the pop out.

    If you are still struggling with the data not updating, you might need to just add a setState(() {}) around your update call.

    Login or Signup to reply.
  3. Instead of using pop, you should push the user to the page. Much like onions, apps have (previously loaded)layers. Try this in the AppBar:

    leading: IconButton(
     icon:Icons(Icons.arrow_back),
     onTap() {
      Navigator.pushAndRemoveUntil(context,
       MaterialPageRoute(
        builder: (BuildContext context) {
         return const Inicio();
        }), (r) {
         return false;
        });}//Maybe you should use a different one if you still want to keep the arrows or something related
    ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search