Search code examples
flutterflutter-layoutflutter-dependenciesflutter-animationflutter-test

How can I delete a task from my task list in flutter


I've created a to do list application. Here I used provider package in my main.dart file and I returned a file which is TaskData so that I can create methods in there and use them at the entire app.

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

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

  // You can see the ChangeNotifierProvider that returns TaskData.
  @override
  Widget build(BuildContext context) {
    return  ChangeNotifierProvider(
      create: (context) => TaskData(),
      child: MaterialApp(
        theme: ThemeData.dark(),
        debugShowCheckedModeBanner: false,
        home: const WelcomeScreen(),
      ),
    );
  }
}

In my TaskData file I have a method to delete a task and it's name is:

deleteTaskC

You can see that down here in the code.

class TaskData extends ChangeNotifier {

  // Use this part for CategoryScreen tasks.
  List<Task> cTasks = [
    Task(name: 'Tap on the bottom plus sign to add a new task. ➕'),
    Task(name: 'Write your task title. ✍️'),
    Task(name: 'Tap "Add" to add the task. 👏'),
  ];

  int get cTaskCount {
    return cTasks.length;
  }

  void addTaskC (String newTaskTitle) {
    final task = Task(name: newTaskTitle);
    cTasks.add(task);
    notifyListeners();
  }

  //Here is the method that I meant: 👇
  void deleteTaskC (Task cTask) {
    cTasks.remove(cTask);
    notifyListeners();
  }

I created the cTasks from a Task class which is this:

class Task {
  final String name;
  bool isDone;

  Task({required this.name, this.isDone = false});

  void toggleDone () {
    isDone = !isDone;
  }
}

And here is the ListTile which contains a task that I want to delete while hitting a long press, I created a longPressCallback and used it inside my TaskTile's onLongPress: as you can see down here in the code.

class TaskTileWithContainer extends StatelessWidget {
  const TaskTileWithContainer({
    Key? key,
    required this.taskTitle,
    required this.isChecked,
    required this.checkboxCallback, required this.longPressCallback,
  }) : super(key: key);

  final String taskTitle;
  final bool isChecked;
  final Function checkboxCallback;
  final void Function() ? longPressCallback;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10),
      decoration: BoxDecoration(
          color: Colors.black, borderRadius: BorderRadius.circular(12)),
      width: double.infinity,
      child: ListTile(
        onLongPress: longPressCallback,
        title: Text(
          taskTitle,
          style: TextStyle(
            decoration: isChecked ? TextDecoration.lineThrough : null,
            color: isChecked ? Colors.white.withOpacity(0.4) : Colors.white.withOpacity(0.9),
          ),
        ),
        trailing: Checkbox(
          checkColor: Colors.white.withOpacity(0.6),
          activeColor: Colors.black,
          value: isChecked,
          onChanged: (newValue) {
            checkboxCallback(newValue);
          },
        ),
      ),
    );
  }
}

And finally I use the callBack from my CategoryScreen which contains the TaskTile, I used setState to update my screen and delete a TaskTile at the current index while hitting longPress on my task tile. You can see from the code below:

ListView.builder(
                        itemBuilder: (context, index) {
                          return TaskTileWithContainer(
                            taskTitle: Provider.of<TaskData>(context).cTasks[index].name,
                            isChecked: Provider.of<TaskData>(context).cTasks[index].isDone,
                            checkboxCallback: (checkboxState) {
                              setState(() {
                                Provider.of<TaskData>(context, listen: false).cTasks[index].toggleDone();
                              });
                            },
                            //Here is the callback to delete a task at a current index.
                            longPressCallback: () {
                              setState(() {
                                Provider.of<TaskData>(context, listen: false).deleteTaskC(TaskData().cTasks[index]);
                              });
                            },
                          );
                        },
                        itemCount: Provider.of<TaskData>(context).cTaskCount,
                      ),

Here is the CategoryScreen where the tasks exist and I want to use the deleteTaskC method to delete a task at the current index.


Solution

  • You already have the list index... so, you can use the removeAt clause.

    myList.removeAt(index);
    

    Edit

    in your remove code :

    void deleteTaskC (Task cTask, int index) {
        cTasks.removeAt(index);
        notifyListeners();
      }
    

    In your longPress:

    longPressCallback: () {
    
       Provider.of<TaskData>(context, listen: 
          false).deleteTaskC(TaskData().cTasks, index);
       setState(() {});
    },