hanshengchiu / reorderables

Reorderable table, row, column, wrap, and sliver list that allow drag and drop of the children. https://pub.dartlang.org/packages/reorderables
MIT License
740 stars 170 forks source link

ReorderableWrap - disable reordering for specific items #89

Open e-e opened 4 years ago

e-e commented 4 years ago

Is it possible to disable drag for specific items in the ReorderableWrap class? My specific use case is to create a photo upload screen that allows a user to upload a set number of images, building up a grid as they add photos. I would like the last item in the grid to be a "+" button used for adding the next image, but i do not want them to be able to reorder this item.

Victor-Dev77 commented 4 years ago

I've the same problem for the same use...

peak77 commented 4 years ago

I've the same problem for the same use.

e-e commented 3 years ago

In the meantime, in case it can help someone else, this is roughly my workaround:

class MyWidget extends StatelessWidget {
   List<MyGridItemWidget> gridItems = [];

  // ...

  @override
  Widget build(BuildContext context) {
    this.gridItems = this.gridItems.where((element) => !element.isButton).toList();
    this.gridItems.add(MyGridItemWidget(isButton: true));

    return ReorderableWrap(children: this.gridItems);
  }
}

The button is still draggable, but will always be render as the last grid item.

Kal-Elx commented 3 years ago

@e-e I'm doing the same thing.

I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)
diickens commented 3 years ago

@Kal-Elx good workaround.. but the problem is the Tile is still reordable (move another tile on its place) would be nice to have the ability to deactivate that.

Kal-Elx commented 3 years ago

@diickens Yes, my solution was to enforce that in onReorder. It's quite easy if you just want to ensure that tiles can't be moved beyond the unmovable tile like in a photo upload screen.

Here's how I implemented it. You can also take a look at the rest of the widget for inspiration on a photo upload screen.

https://github.com/dibbs-team/dibbs/blob/main/lib/widgets/upload/image_sequence_picker/image_sequence_picker.dart#L90-L99

mattia-venturini commented 3 years ago

If the item that should not be draggable is the first or the last you can use either the parameter header or footer. They seem to work fine.

3111279132 commented 3 years ago

@e-e I'm doing the same thing.

I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)

This is available; thanks

KuuBee commented 3 years ago

@e-e I'm doing the same thing.

I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)

This can also take effect

ReorderableWrap(
      children: [
        ReorderableWidget(
          key: ValueKey('Disable drag'),
          reorderable: false,
          child: Text('Disable drag'),
        ),
        ReorderableWidget(
          key: ValueKey('Enable drag'),
          reorderable: true,
          child: Text('Enable drag'),
        ),
      ],
      needsLongPressDraggable: false,
      onReorder: _onReorder,
    );
yoniker commented 3 years ago

@e-e I'm doing the same thing. I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)

This can also take effect

ReorderableWrap(
      children: [
        ReorderableWidget(
          key: ValueKey('Disable drag'),
          reorderable: false,
          child: Text('Disable drag'),
        ),
        ReorderableWidget(
          key: ValueKey('Enable drag'),
          reorderable: true,
          child: Text('Enable drag'),
        ),
      ],
      needsLongPressDraggable: false,
      onReorder: _onReorder,
    );

This is the most native solution I can see, but still this allows to change the position of non-draggables by dragging over, and the footer widget doesn't obey the same placement rules as the other widgets (for example in a Wrap it's "after" the wrap eg underneath instead of whereever the next element would have been in a wrap).

It's really the only dent I can see in this amazing package which is intuitive and works well!

@diegotori I'm facing the exact same scenario and I can see that this issue is open for a while, is it a huge hassle to implement a "locked" item which obeys the same rules as the original Widget(eg Wrap,Column,Row etc)?

cgowthamanmca commented 2 years ago

@e-e I'm doing the same thing. I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)

This can also take effect

ReorderableWrap(
      children: [
        ReorderableWidget(
          key: ValueKey('Disable drag'),
          reorderable: false,
          child: Text('Disable drag'),
        ),
        ReorderableWidget(
          key: ValueKey('Enable drag'),
          reorderable: true,
          child: Text('Enable drag'),
        ),
      ],
      needsLongPressDraggable: false,
      onReorder: _onReorder,
    );

Thanks lot

MarnoDev commented 2 years ago

@e-e I'm doing the same thing. I'm solving this by wrapping the non movable widgets in:

GestureDetector(
      onLongPress: () {}, // Override onLongPress to make item unmovable.
      child: ...
)

This can also take effect

ReorderableWrap(
      children: [
        ReorderableWidget(
          key: ValueKey('Disable drag'),
          reorderable: false,
          child: Text('Disable drag'),
        ),
        ReorderableWidget(
          key: ValueKey('Enable drag'),
          reorderable: true,
          child: Text('Enable drag'),
        ),
      ],
      needsLongPressDraggable: false,
      onReorder: _onReorder,
    );

Not work