flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.37k stars 27.55k forks source link

Option to disable reordering for specific items #127812

Open tomasbaran opened 1 year ago

tomasbaran commented 1 year ago

Is there an existing issue for this?

Use case

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.

Another case is having a todo list: ReorderableListView where the last item would be "COMPLETED" todoes which should not be draggable.

There are some workaround, so no other item can reorder that one but basically none that I know of is able to get rid of this reordering effect:

https://github.com/flutter/flutter/assets/25743901/41126664-243c-410e-8706-e764e949239d

Proposal

Add an option: enableReoreding' so it'd be another option that'd go next to thekey` parameter.

tomasbaran commented 1 year ago

You can find partial workarounds here but again no full workaround found: https://github.com/hanshengchiu/reorderables/issues/89#:%7E:text=movable%20widgets%20in%3A-,GestureDetector(%0A%20%20%20%20%20%20onLongPress%3A%20()%20%7B%7D%2C%20//%20Override%20onLongPress%20to%20make%20item%20unmovable.%0A%20%20%20%20%20%20child%3A%20...%0A),-6

navaronbracke commented 1 year ago

You can disable the drag handle for the last item (by not wrapping the widget in a ReorderableDragStartListener), but that does not prevent the last item from moving away from the drag proxy item, even though it does not participate in being draggable itself.

However, you could use a SliverReorderableList that contains the reorderable items, and add the last item outside of that list, below the SliverReorderableList in the widget tree.

tomasbaran commented 1 year ago

If the item that should not be draggable is the first one or the last one, the parameter header or footer should be used. This may actually solve the issue overall.

plammens commented 3 months ago

I have use cases where the item that should not be draggable is neither at the start or the end. For example, in an agenda view, I have a divider that indicates the current time right now, separating past events from future events.

jlambright commented 6 hours ago

I'm in a similar boat to @plammens , and need to be able to add "Add Here" widgets as separators to each list item. Obviously, I don't want those to be draggable. I could nerf dragging on those separator widgets...but that seems like a bad bandaid.

  void onReorder(int oldIndex, int newIndex) {
    // Only allow reordering if both indices correspond to element
    if (oldIndex % 2 == 0 && newIndex % 2 == 0) {
      // Reordering objectives
      int oldElementIndex = oldIndex ~/ 2;
      int newElementIndex = newIndex ~/ 2;

      insertElement(
          newElementIndex, reordableList.removeAt(oldElementIndex));
    }
  }

This is far from perfect.