3

I'm using this reorderables package. This package works by having a list of children widgets that are each wrapped with a Draggable and put inside a DragTarget. Before that the childs key is assigned to a GlobalObjectKey.
After the dragTarget is created, it is assigned(or rebuild?) to a KeyedSubTree:

dragTarget = KeyedSubtree(key: keyIndexGlobalKey, child: dragTarget);

According to the comments in the package source code, this should preserve the child widgets state (toWrap) when being dragged:

// We pass the toWrapWithGlobalKey into the Draggable so that when a list
// item gets dragged, the accessibility framework can preserve the selected
// state of the dragging item.
final GlobalObjectKey keyIndexGlobalKey = GlobalObjectKey(toWrap.key);

The reordering itself happens not with the DragTarget accepting the Draggable dragged into it, but rather by using the DragTarget around each child to get index of the current position the Draggable is hovering over. When the Draggable is let go, a reorder function will get called, which removes the widget (that was being dragged) from the list and inserting it into the new position.

Now comes my problem: The state of the widget is not being preserved. I made a simple TestWidget to test this:

class TestWidget extends StatefulWidget{
  @override
  _TestWidgetState createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {

    Color boxColor;

    @override
    void initState() {
        super.initState();
        boxColor= Colors.blue;
    }

    @override
    Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
                decoration: BoxDecoration(color: boxColor),
                child: Text("Test"),
            ),
              FlatButton(
                  onPressed: (){
                    setState(() {
                        boxColor = Colors.red;
                    });
                  },
                  padding: EdgeInsets.all(8.0),
                  child: Text("Change to Red"),
                  color: Colors.grey,
              )
          ],
        );
    }
}

This widget has a Container with a initial blue background (boxColor) and a button. When the button is pressed, it will change the boxColor to red. The moment the dragging on the widget is initiated, it is rebuild and defaults to the initial state (at least the Draggable feedback is). After the reordering that doesn't change and the widget is still in it's default state.

My plan here is to have a list of different custom widgets, where the User can modify their content and if they are not happy with the order, they can drag those widgets around and rearrange them.

My question is: How do I preserve the state of my widgets?

I'm thinking of creating a class for each widget with all state relevant variables and use that to build my widgets but that seems very bloated and not really in the mind of flutter. Isn't that supposed to be the role of the state of the StatefulWidget?

EDIT:
So I solved my problem by creating an additional class for my widget state with ChangeNotifier and then moving all my variables that I want to keep track of into this class. So I basically now have two lists, one for my widgets in the reorderable list and one for their states. I still think that this is kinda scuffed. If a widget in my list has additional children of its own, I would need to create separate state classes for each of them that need it and save them somewhere. This can get very messy, very quickly.

Levaru
  • 51
  • 4

0 Answers0