Omar Elwaliely
Omar Elwaliely

Reputation: 11

Is there a way to remove a widget from the tree after button press?

Flutter newbie here. I'm trying to make a simple to-do list that I'm using to build up my skills. The idea is there is a to-do list that you can move the properties up and down and once you complete a task you check it off and it should display a checkmark and maybe eventually play an animation and remove it. For now, I'm stuck on just removing it, I had a few implementation ideas, but a lot of them will require me to restart my code. Is there a way to make it so that once I am done with a specific widget I can delete it or replace it with another, noting the fact that these widgets are in a list? code for reference:


class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var checkboxes = [
    Checkboxstate(title: "test"),
    Checkboxstate(title: "test2"),
    Checkboxstate(title: "test3"),
    Checkboxstate(title: "tes4t"),
  ];
  bool value = true;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("To-Do"),
        backgroundColor: Colors.purple,
      ),
      backgroundColor: Colors.blue,
      body: Container(
        padding: EdgeInsets.all(10),
        child: ReorderableListView(
          shrinkWrap: true,
          onReorder: (int oldIndex, int newIndex) {
            setState(() {
              if (oldIndex < newIndex) {
                newIndex -= 1;
              }
              var item = checkboxes.removeAt(oldIndex);
              checkboxes.insert(newIndex, item);
            });
          },
          children: [
            ...checkboxes.map(buildBox).toList(),
          ],
        ),
      ),
    );
  }

  Card buildBox(Checkboxstate checkbox) {
    return Card(
      key: UniqueKey(),
      child: CheckboxListTile(
        title: Text(checkbox.title),
        key: UniqueKey(),
        controlAffinity: ListTileControlAffinity.leading,
        value: checkbox.value,
        onChanged: (value) {
          setState(() {
            checkboxes.removeAt();
            checkbox.value = value;
          });
        },
      ),
    );
  }
}

class Checkboxstate {
  String title;
  bool value;
  Checkboxstate({this.title, this.value = false});
}

EDIT: As suggested by Prabhanshu I followed his steps and instead used the item builder; however, there is a new issue: the reorderablelistview now doesn't work. My idea was that the reason was that the index was different for the reorderable list than the checkbox widget I create, but I am still unable to find a solution.

new code:



import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var checkboxes = [
    Checkboxstate(title: "test"),
    Checkboxstate(title: "test2"),
    Checkboxstate(title: "test3"),
    Checkboxstate(title: "tes4t"),
  ];
  bool value = true;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("To-Do"),
        backgroundColor: Colors.purple,
      ),
      backgroundColor: Colors.blue,
      body: Container(
        padding: EdgeInsets.all(10),
        child: ReorderableListView.builder(
          shrinkWrap: true,
          onReorder: (int oldIndex, int newIndex) {
            setState(() {
              if (oldIndex < newIndex) {
                newIndex -= 1;
              }
              var item = checkboxes.removeAt(oldIndex);
              checkboxes.insert(newIndex, item);
            });
          },
          itemCount: checkboxes.length,
          itemBuilder: (context, index) {
            Checkboxstate box = checkboxes.elementAt(index);
            return buildBox(box, index);
          },
        ),
      ),
    );
  }

  Card buildBox(Checkboxstate checkbox, int index) {
    return Card(
      key: UniqueKey(),
      child: CheckboxListTile(
        title: Text(checkbox.title),
        key: UniqueKey(),
        controlAffinity: ListTileControlAffinity.leading,
        value: checkbox.value,
        onChanged: (value) {
          setState(() {
            checkbox.value = value;
            checkboxes.removeAt(index);
          });
        },
      ),
    );
  }
}

class Checkboxstate {
  String title;
  bool value;
  Checkboxstate({this.title, this.value = false});
}

Upvotes: 1

Views: 2657

Answers (2)

Prabhanshu Tiwari
Prabhanshu Tiwari

Reputation: 54

This will definitely help you.

replace the build method body with this

Scaffold(
  appBar: AppBar(
    title: Text("To-Do"),
    backgroundColor: Colors.purple,
  ),
  backgroundColor: Colors.blue,
  body: Container(
    padding: EdgeInsets.all(10),
    child: ReorderableListView.builder(
      shrinkWrap: true,
      onReorder: (int oldIndex, int newIndex) {
        setState(() {
          if (oldIndex < newIndex) {
            newIndex -= 1;
          }
          var item = checkboxes.removeAt(oldIndex);
          checkboxes.insert(newIndex, item);
        });
      },
      itemCount: checkboxes.length,
      itemBuilder: (context, index) {
        Checkboxstate box = checkboxes.elementAt(index);
        return buildBox(box, index);
      },
    ),
  ),
);

and

Replace this method also

Card buildBox(Checkboxstate checkbox, int index) {
return Card(
  key: UniqueKey(),
  child: CheckboxListTile(
    title: Text(checkbox.title),
    key: UniqueKey(),
    controlAffinity: ListTileControlAffinity.leading,
    value: checkbox.value,
    onChanged: (value) {
      setState(() {
        checkboxes.removeAt(index);
        checkbox.value = value;
      });
    },
  ),
);

}

Upvotes: 0

Rohan Thacker
Rohan Thacker

Reputation: 6357

If drag to dismiss is an option:

What you're looking for here is the Dismissible Widget, which as the docs describe is a widget that can be dismissed by dragging in the indicated direction.

Check out the flutter cookbook tutorial for a detailed explanation on how to use this widget.

Upvotes: 0

Related Questions