本例使用Draggable和DragTarget嵌套使用,完成一个可拖拽并且可接受数据的Widget
用DragTarget作为Draggable的child,真正展示的UI通过DragTarget的builder来完成。
本例效果如下:
有上下两个可拖拽的Widget,都可以接收拖拽过来的数据并处理。
和之前一样,先来一个空白页。
void main() => runApp(new MyApp());
///用于展示Demo的界面,其中的MaterialApp、ThemeData、AppBar都是不必要的,只是稍微美观一点。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: new AppBar(
title: new Text("DraggableDemo"),
),
// body: MyDraggable()),
// body: Drag2TargetPage()),
body: DraggableItemDemo()),//这个是Draggable和DragTarget的组合Widget
);
}
}
由于组合后的Widget是需要状态可变的,使用StatefulWidget作为父类。
将上一篇中的DragTarget作为Draggable的child,DragTarget的构成可以保持不变。
class MyDraggableTarget<T> extends StatefulWidget {
final T data;
MyDraggableTarget({@required this.data, Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => _MyDraggableTargetState(text: data);
}
class _MyDraggableTargetState extends State<MyDraggableTarget> {
var text;
_MyDraggableTargetState({@required this.text});
@override
Widget build(BuildContext context) {
return Draggable(
data: text,
child: Container(//仅用于保持样式,可以使用DragTarget作为直接child。
width: 150.0,
height: 150.0,
color: Colors.red[500],
child: DragTarget(
onWillAccept: (data) {
print("data = $data onWillAccept");
return data != null;
},
onAccept: (data) {
print("data = $data onAccept");
setState(() {
text = data;
});
},
onLeave: (data) {
print("data = $data onLeave");
},
builder: (context, candidateData, rejectedData) {
return Container(
width: 150.0,
height: 150.0,
color: Colors.blue[500],
child: Center(
child: Text(text),
),
);
},
),
),
feedback: Container(
width: 150.0,
height: 150.0,
color: Colors.blue[500],
child: Icon(Icons.feedback),
),
);
}
}
这样一个可拖拽可接受数据的Widget就组合好了,
使用一个Column存放两个这样的Widget,即可实现互相拖动和接收。
class DraggableItemDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Divider(),
MyDraggableTarget(
data: "123",
),
Divider(),
MyDraggableTarget(
data: "456",
),
],
);
}
}
基于这样一个组合Widget,我们可以尝试让ListView/GridView的item可拖动,进而实现拖动排序。