I want to have two containers in a Row that each have their own lists of Card widgets.
I think that combining the linked library with Flutter DragTarget could possibly be one working solution, but I'm not sure.
import 'package:flutter/material.dart';
class DragDropExample extends StatefulWidget {
@override
_DragDropExampleState createState() => _DragDropExampleState();
}
class _DragDropExampleState extends State<DragDropExample> {
List<Widget> libraryCards = [
Card(
color: Colors.blue[100],
child: const Padding(
padding: EdgeInsets.all(16),
child: Text("Card A"),
),
),
Card(
color: Colors.blue[100],
child: const Padding(
padding: EdgeInsets.all(16),
child: Text("Card B"),
),
),
Card(
color: Colors.blue[100],
child: const Padding(
padding: EdgeInsets.all(16),
child: Text("Card C"),
),
),
];
List<Widget> droppedCards = [];
void _addNewItem(Widget child) {
setState(() {
droppedCards.insert(
0,
_buildListItem(child),
);
});
}
Widget _buildListItem(Widget child) {
return SizedBox(key: UniqueKey(), child: child);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Drag and Drop Example')),
body: Row(
children: [
// Left Container: Library
Expanded(
flex: 1,
child: Container(
color: Colors.blue[50],
padding: const EdgeInsets.all(8),
child: ReorderableListView(
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final item = libraryCards.removeAt(oldIndex);
libraryCards.insert(newIndex, item);
});
},
children: libraryCards
.map(
(card) => Draggable<Widget>(
key: UniqueKey(),
data: card,
feedback: Material(child: card),
childWhenDragging: Opacity(opacity: 0.5, child: card),
child: card),
)
.toList(),
),
),
),
// Right Container: Droppable List
Expanded(
flex: 2,
child: Container(
color: Colors.green[50],
padding: const EdgeInsets.all(8),
child: DragTarget<Widget>(
onAccept: (data) {
setState(() {
_addNewItem(data);
});
},
builder: (context, candidateData, rejectedData) {
return ReorderableListView(
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final item = droppedCards.removeAt(oldIndex);
droppedCards.insert(newIndex, item);
});
},
children: droppedCards,
);
},
),
),
),
],
),
);
}
}
If you want to re-arrange the card library on the left or right, just long press and drag to the desired position. But to drag from left to right container just drag straight way. NB. I drop the item on the top of the list.