I've tried flutter_reorderable_list and dragable_flutter_list but none of them worked properly - there was some unwanted artifacts during dragging.
So I've tried to make own solution:
ListView.builder(
itemBuilder: (context, index) => buildRow(index),
itemCount: trackList.length,
),
Widget buildRow(int index) {
final track = trackList[index];
ListTile tile = ListTile(
title: Text('${track.getName()}'),
);
Draggable draggable = LongPressDraggable<Track>(
data: track,
axis: Axis.vertical,
maxSimultaneousDrags: 1,
child: tile,
childWhenDragging: Opacity(
opacity: 0.5,
child: tile,
),
feedback: Material(
child: ConstrainedBox(
constraints:
BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
child: tile,
),
elevation: 4.0,
),
);
return DragTarget<Track>(
onWillAccept: (track) {
return trackList.indexOf(track) != index;
},
onAccept: (track) {
setState(() {
int currentIndex = trackList.indexOf(track);
trackList.remove(track);
trackList.insert(currentIndex > index ? index : index - 1, track);
});
},
builder: (BuildContext context, List<Track> candidateData,
List<dynamic> rejectedData) {
return Column(
children: <Widget>[
AnimatedSize(
duration: Duration(milliseconds: 100),
vsync: this,
child: candidateData.isEmpty
? Container()
: Opacity(
opacity: 0.0,
child: tile,
),
),
Card(
child: candidateData.isEmpty ? draggable : tile,
)
],
);
},
);
}
I guess, this is not the best solution, and I'm maybe will change it further, but for now it works quite well