In a flutter application that I'm building(a to-do list basically), I wish to delete all the completed tasks(active checkboxes) with a single button. As of now, it functions as expected ONLY WHEN the last checkbox is active and all the other active checkboxes(if any) are right above it, simultaneously.

The app malfunctions if there is even 1 inactive checkbox after an active checkbox.

Here's the code for the class that creates the task widget :

class addnote extends StatefulWidget {

  final String task_txt;
  final int index;// receives the value

  addnote({ Key key, this.task_txt, this.index }): super(key: key);

  @override
  _addnoteState createState() => _addnoteState();
}

class _addnoteState extends State<addnote> {

  bool value=false;

  Widget txt_strike(String to_strike, bool str_value){
    return str_value ?
    AutoSizeText(to_strike,style: TextStyle(
      decoration: TextDecoration.lineThrough,
      fontFamily: "Quicksand",
      fontSize: 20.0,
      color: Colors.grey,
    ),
    maxLines: 2,
      overflow: TextOverflow.ellipsis,
    )
        :
    AutoSizeText(to_strike,style: TextStyle(
      //decoration: TextDecoration.lineThrough,
      fontFamily: "Quicksand",
      fontSize: 20.0,
      color: Colors.black,
    ),
    maxLines: 2,
      overflow: TextOverflow.ellipsis,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        decoration: BoxDecoration(
        borderRadius:BorderRadius.circular(4.0),
        boxShadow: [BoxShadow(
        color:Colors.grey,
        offset: Offset(-6.0,4.0),
        blurRadius: 4.0,
        )],
            color: Colors.white
        ),
         margin: EdgeInsets.symmetric(vertical: 5.0,horizontal: 3.0),
      child:InkWell(

        onTap: (){setState(() {
          value=!value;
          w_checks[widget.index]=!w_checks[widget.index];
        });},
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Expanded(flex:1,
              child: CircularCheckBox(
                  disabledColor: Colors.white,
                  activeColor: Colors.green,
                  value: value,
                  onChanged:(bool _changed)
                  {
                    // print(w_checks[Index]);
                    setState(() {
                      value=!value;
                      w_checks[widget.index]=!w_checks[widget.index];
                    });
                  }),
            ),
            Expanded(flex:5,
                child: txt_strike(widget.task_txt, value)),
           ],
        ),
      )
    );
  }
}

And here's the code for the func that deletes the task widget :

void del_task(){
   int count=0;
   for(int i=0; i<w_checks.length; i++)
   {
     if(w_checks[i]==true)
       count++;
   }
   while(count>=0)
   {
     for(int j=0; j<w_checks.length; j++)
     {
       if(w_checks[j]==true)
       {
         setState(() {
           { w_tasks.removeAt(j);  //w_tasks is the list of all the tasks
           w_checks.removeAt(j);   //w_checks is the list that stores bool values corresponding to each checkbox
           }
         });
         for(int k=j; k<w_checks.length; k++)
           {
             w_tasks[k]=w_tasks[k+1];
             w_checks[k]=w_checks[k+1];

           }
         break;
       }
     }
     count--;
   }
 }

Hope I was able to describe my problem, kindly help.


Solution 1: L. Gangemi

I'm not really shure about what are you doing inside del_task() but I think your problem is caused by the for cycle in which you are moving all later objects down by one position.

That operation is already performed by the "list.removeAt(index)" method, as u can see from the documentation: https://api.dart.dev/stable/2.10.2/dart-core/List/removeAt.html

I would have changed the code like this:

void del_task(){
   for(int i=0; i<w_checks.length; i++)
   {
       if(w_checks[i]==true)
       {
         setState(() {
           w_tasks.removeAt(i);  
           w_checks.removeAt(i);   
         });
         i--;
       }
   }
 }

I don't understand why you needed the count variable.

The code I posted should iterate throught w_checks. When it found a "true" value, it will call removeAt(i) and then decrease index by one.