我想在一行中有两个容器,每个容器都有自己的卡片小部件列表。
我认为将链接库与 Flutter DragTarget 相结合可能是一种可行的解决方案,但我不确定。
import 'package:flutter/material.dart';
class DragDropExample extends StatefulWidget {
@override
_DragDropExampleState createState() => _DragDropExampleState();
}
class _DragDropExampleState extends State<DragDropExample> {
List<String> libraryCards = ["Card A", "Card B", "Card C"];
List<String> droppedCards = [];
int? dropIndex; // To track where the card will be dropped
@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: Wrap(
spacing: 8,
runSpacing: 8,
children: libraryCards.map((card) {
return Draggable<String>(
data: card,
feedback: Material(
child: Card(
color: Colors.blue[200],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(card),
),
),
),
childWhenDragging: Opacity(
opacity: 0.5,
child: Card(
color: Colors.blue[100],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(card),
),
),
),
child: Card(
color: Colors.blue[100],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(card),
),
),
);
}).toList(),
),
),
),
// Right Container: Droppable List
Expanded(
flex: 2,
child: Container(
color: Colors.green[50],
padding: const EdgeInsets.all(8),
child: DragTarget<String>(
onAccept: (data) {
setState(() {
droppedCards.insert(dropIndex ?? droppedCards.length, data);
dropIndex = null; // Reset the drop index
});
},
onMove: (details) {
RenderBox renderBox = context.findRenderObject() as RenderBox;
double localDy = renderBox.globalToLocal(details.offset).dy;
double itemHeight = 70; // Approximate height of each card
dropIndex = (localDy / itemHeight).floor().clamp(0, droppedCards.length);
setState(() {});
},
onLeave: (_) => setState(() => dropIndex = null),
builder: (context, candidateData, rejectedData) {
return Column(
children: [
for (int i = 0; i <= droppedCards.length; i++) ...[
if (i == dropIndex)
const Divider(
color: Colors.green,
thickness: 3,
),
if (i < droppedCards.length)
Draggable<String>(
data: droppedCards[i],
feedback: Material(
child: Card(
color: Colors.green[200],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(droppedCards[i]),
),
),
),
childWhenDragging: Opacity(
opacity: 0.5,
child: Card(
color: Colors.green[100],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(droppedCards[i]),
),
),
),
onDragCompleted: () => droppedCards.removeAt(i),
child: Card(
color: Colors.green[100],
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(droppedCards[i]),
),
),
),
],
],
);
},
),
),
),
],
),
);
}
}