Reputation: 181
I am trying to create a ListView that meets the following criteria:
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
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
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
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
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
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
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