import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class DragGridView extends StatefulWidget {
@override
State<StatefulWidget> createState() => _DragGridState();
}
class _DragGridState extends State<DragGridView> {
Map<String, List<String>> data = {
"List A" : ['A1', 'A2', 'A3', 'A4','A5','A6','A7','A8','A9'],
"List B" : ['B1', 'B2', 'B3', 'B4','B5','B6','B7','B8','B9'],
};
String movingValue;
@override
Widget build(BuildContext context) {
List<Widget> children = [];
data.forEach((key, list) {
children.add(Text(key));
children.add(GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0,
childAspectRatio: 1),
children: buildItems(list),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true
));
children.add(SizedBox(height: 20,));
});
return Scaffold(
appBar: AppBar(title: Text('Draggable Demo')),
body: SingleChildScrollView(
child: Center(
child: Column(children: children),
),
),
);
}
// 生成GridView的items
List<Widget> buildItems(List list) {
List<Widget> items = [];
for (String title in list) {
items.add(Center(child: draggableItem(title),));
}
return items;
}
// 生成可拖动的item
Widget draggableItem(value) {
return Draggable(
data: value,
child: DragTarget(
builder: (context, candidateData, rejectedData) {
return baseItem(value);
},
onWillAccept: (moveData) {
var accept = moveData != null;
if (accept) {
exchangeItem(moveData, value, false);
}
return accept;
},
onAccept: (moveData) {
exchangeItem(moveData, value, true);
},
),
feedback: baseItem(value),
childWhenDragging: null,
onDragStarted: () {
setState(() {
movingValue = value;//记录开始拖拽的数据
});
},
onDraggableCanceled: (Velocity velocity, Offset offset) {
setState(() {
movingValue = null;//清空标记进行重绘
});
},
);
}
Widget baseItem(value) {
if (value == movingValue) {
return Container();
}
return Container(
width: 110,
height: 110,
color: Colors.blue,
child: Center(
child: Text(
value,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.yellowAccent),
),
),
);
}
// 重新排序
void exchangeItem(moveData, toData, onAccept) {
setState(() {
for (List<String> list in data.values) {
if (list.contains(moveData)) {
if (list.contains(toData)) {
int toIndex = list.indexOf(toData);
list.remove(moveData);
list.insert(toIndex, moveData);
} else {
var toList = [];
for (var value in data.values) {
if (value.contains(toData)) {
toList = value;
break;
}
}
int toIndex = toList.indexOf(toData);
list.remove(moveData);
toList.insert(toIndex, moveData);
}
break;
}
}
if (onAccept) {
movingValue = null;
}
});
}
}
|