skip to Main Content

in my Todo App list, I’m trying to make the global state in my task list view but I’m facing some issues. I’m using StatefulWidget and StatelessWidget. In StatelessWidget Checkbox onChanged I want to toggle the Checkbox value and comes from the parent Widget but it’s showing some setState() build issue Please have a look If you can.

tasks_lists.dart


import 'package:flutter/material.dart';

class TasksList extends StatefulWidget {
  const TasksList({super.key});

  @override
  State<TasksList> createState() => _TasksListState();
}

class _TasksListState extends State<TasksList> {
  bool isChecked = false;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(
        'List 1',
        style: TextStyle(
          color: Colors.black,
          decoration:
              isChecked ? TextDecoration.lineThrough : TextDecoration.none,
        ),
      ),
      trailing: TaskCheckbox(
        checkBoxState: isChecked,
        toggleCheckboxState: (bool checkedBoxState) {
          setState(
            () {
              isChecked = checkedBoxState;
            },
          );
        },
      ),
    );
  }
}

class TaskCheckbox extends StatelessWidget {
  final bool checkBoxState;
  final Function? toggleCheckboxState;

  const TaskCheckbox({
    super.key,
    required this.checkBoxState,
    this.toggleCheckboxState,
  });

  @override
  Widget build(BuildContext context) {
    return Checkbox(
      value: checkBoxState,
      onChanged: toggleCheckboxState!(checkBoxState),
      activeColor: Colors.lightBlueAccent,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(2.0),
      ),
      side: MaterialStateBorderSide.resolveWith(
        (states) => BorderSide(
          width: 2.0,
          color: Colors.black,
        ),
      ),
    );
  }
}

4

Answers


  1. You are changing value/state so you have to make TaskCheckbox a Stateful widget.

    Login or Signup to reply.
  2. onChange is a Fuction(bool). try to change TaskCheckbox to this:

    class TaskCheckbox extends StatelessWidget {
     final bool checkBoxState;
      final Function(bool)? toggleCheckboxState;
    
      const TaskCheckbox({
        super.key,
        required this.checkBoxState,
        this.toggleCheckboxState,
      });
      @override
      Widget build(BuildContext context) {
        return Checkbox(
          value: checkBoxState,
          onChanged: toggleCheckboxState!,
          activeColor: Colors.lightBlueAccent,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(2.0),
          ),
          side: MaterialStateBorderSide.resolveWith(
                (states) => BorderSide(
              width: 2.0,
              color: Colors.black,
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  3. Your toggleCheckboxState function call during building the UI, so you need to put it inside addPostFrameCallback so it run after UI builds, like this:

    toggleCheckboxState: (bool checkedBoxState) {
    
       WidgetsBinding.instance.addPostFrameCallback((_) {
           setState(
             () {
               isChecked = checkedBoxState;
             },
           );  
       });
              
    },
    
    Login or Signup to reply.
  4. This means that the function is called during build,

    onChanged: toggleCheckboxState!(checkBoxState),
    

    while this calls the function when Checkbox is tapped.

    onChanged: (checkBoxState) => toggleCheckboxState!(checkBoxState),
    

    Take a look of Introduction to widgets.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search