'Flutter web - ReordorableListView with + button on hover between fields

I am working on a Flutter Web project, and we would like to have a ReordorableListView design. We also would like to have a "+" button between the cards of the list when the user hovers between 2 elements (to then add an element at the chosen position).

I tried to do it by including in the list a widget (which is transparent and becomes a "+" when hovered). But by doing this, this widget is also draggable by the user which I don't want.

Here is a simple example:

class Screen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      onReorder: (int oldIndex, int newIndex) {},
      children: [
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 0'),
          ),
          key: Key('key0'),
        ),
        PlusButton(
          key: Key('plusButton'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 1'),
          ),
          key: Key('key1'),
        ),
        const Card(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Value 2'),
          ),
          key: Key('key2'),
        ),
      ],
    );
  }
}

class PlusButton extends StatefulWidget {
  PlusButton({Key key}) : super(key: key);
  @override
  _PlusButtonState createState() => _PlusButtonState();
}

class _PlusButtonState extends State<PlusButton> {
  bool isHovered = false;
  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (_) {
        print('enter');
        setState(() {
          isHovered = true;
        });
      },
      onExit: (_) {
        print('exit');
        setState(() {
          isHovered = false;
        });
      },
      child: Container(
        height: 20,
        width: 50,
        color: Colors.red, // Should be transparent, red to see it in the example
        child: isHovered
            ? IconButton(
                iconSize: 10,
                icon: const Icon(Icons.add),
                onPressed: () {},
              )
            : null,
      ),
    );
  }
}

The list :

enter image description here

When the button is hovered:

enter image description here

As you can see, the button is also draggable:

enter image description here

How can I display a "+" button between 2 elements when the user hovers there ?



Solution 1:[1]

Maybe you can look inside ReorderableListView, there is a buildDefaultDragHandle param in there. By setting it to false, the widget won't automatically make items draggable anymore, but it let you wrap your item with the ReorderableDragStartListener or ReorderableDelayedDragStartListener(needs long press to trigger dragging).

Off-topic: I have a similar feature-request too, but it's to make the "plus button" hover on top of the ListView, not in between the items.

Flutter is not good at creating unordinary layout by it's raw abilities, tried to use a SizedBox.shrink combined with OverflowBox, it graphically works but the HitTest won't work because the overflow part won't count.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1