Wagner Maciel
Wagner Maciel

Reputation: 181

Is it possible to disable reordering a single item in a reorderable listview in flutter?

I am trying to create a ListView that meets the following criteria:

  1. The items in the ListView are categorized into sections with headers for each section
  2. The items can be dragged from one section to another
  3. The section headers are not draggable

This would easy to accomplish if ReorderableListView allowed you to disable a ListTile from being dragged & dropped (in other words, I would be able to create the headers as ListTile items in the ListView and disable dragging and dropping on only them while still allowing everything else to be dragged & dropped), but I can't figure out how. Any tips?

Upvotes: 13

Views: 5511

Answers (7)

Jeffrey
Jeffrey

Reputation: 11

Check out this example
You can set buildDefaultDragHandles to false, then build the drag handler using ReorderableDragStartListener only for non-header items

Upvotes: 1

Alexander Melnikov
Alexander Melnikov

Reputation: 251

You can use ReorderableDragStartListener.

Wrap the sections that need to be non-reorderable with it and pass enabled: false like so:

class HeaderSection extends StatelessWidget {
  const HeaderSection({
    Key? key,
    required this.index,
  }) : super(key: key);

  final int index;

  @override
  Widget build(BuildContext context) {
    return ReorderableDragStartListener(
      index: index,
      enabled: false,
      child: const Text('This header can not be dragged'),
    );
  }
} 

There is also ReorderableDelayedDragStartListener for cases where you want to use long-press to begin reordering.

Upvotes: 1

anjo jy
anjo jy

Reputation: 9

The reorderable list wrap with AbsorbPointer widget

Use AbsorbPointer to disable widgets

 AbsorbPointer(
            absorbing: countList.length <= 1 ? true : false,
            child: ReorderableListView(
                shrinkWrap: true,
                buildDefaultDragHandles: false,
                dragStartBehavior: DragStartBehavior.down,
                physics: const NeverScrollableScrollPhysics(),
                children: <Widget>[
                  for (var i = 0; i < countList.length; i++)
                    Card(
                      elevation: 0,
                      color: customColors().backgroundPrimary,
                      key: ValueKey(
                          countList[i].Name),
                      child: Container(
                        child:Text("Demo")
                      ),
                    ),
                ],
                onReorder:onReoder),
          ),

Upvotes: -1

takudzw_M
takudzw_M

Reputation: 356

This is another workaround.

Wrap the widget you don't want to be moved in a GestureDetector, then override the onLongPress.

 return GestureDetector(
                                  onLongPress: () {},
                                  key: ValueKey(index),
                                  child: Column(
                                      children: List.generate(
                                          3,
                                          (index) => ListTile(
                                              title: Text("TItle test")))),
                                );

Check this https://github.com/hanshengchiu/reorderables/issues/89#:~: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 for the full discussion

Upvotes: 8

Viktor Kadza Jr.
Viktor Kadza Jr.

Reputation: 318

You can add a some type of nonreorderable bool field to tiles , and check it when onReorder is called, and just skip the index change, or do same extra logic for that particular case.

Upvotes: 0

wujek
wujek

Reputation: 11070

You can prevent moving the headers with AbsortPointer etc. as you mentioned, but if the other items are moved into a place that you don't want to allow, you can simply check for this in the onReorder callback and not update the underlying model, so when the user drops the item it will get back to its original place. E.g. if the user tries moving any movable item to be placed before the first header, you detect this (newIndex == 0) and return early.

Upvotes: 1

Wagner Maciel
Wagner Maciel

Reputation: 181

Just discovered the AbsorbPointer and IgnorePointer classes.

Upvotes: 5

Related Questions