描述:
使用Draggable(LongPressDraggable长按拖拽组件属性类似Draggable) 和 DragTarget结合,实现组件的拖拽效果
效果图:
代码:
class DraggblePage extends StatefulWidget {
const DraggblePage({Key? key}) : super(key: key);
@override
State<DraggblePage> createState() => _DraggblePageState();
}
class _DraggblePageState extends State<DraggblePage> {
bool _accept = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Draggable"),
),
body: Center(
child: Column(
children: [
Draggable(
//用于限制child可移动的方向,默认null允许任何方向
// axis: null,
//拖动对象携带的数据可传值给目标控件
data: true,
child: _accept
? Container(height: 100, width: 100)
: _buildDraggable(context),
//拖动时的部件
feedback: _buildFeedback(context),
//拖动时,child部件的显示样式
childWhenDragging: Container(height: 100, width: 100),
//feedback左上角,相对点击锚点的偏移量
// dragAnchorStrategy: (draggable, context, position) {
// },
//拖动时的锚点的x,y与目标范围的相差偏移量,
//锚点拖动到灰色区域才可触发 DragTarget的onAccept事件
feedbackOffset: const Offset(0, 0),
//开始拖动时回调
onDragStarted: () {
print("----------onDragStarted");
},
//拖动中的回调
onDragUpdate: (details) {
print("----------onDragUpdate");
},
//拖动到DragTarget控件上时松手后被目标[DragTarget]接受时的回调。
onDragCompleted: () {
print("----------onDragCompleted");
},
//检测未拖动到目标[DragTarget]控件上时回调。
onDraggableCanceled: (velocity, offset) {
print("----------onDraggableCanceled");
},
//拖动结束时回调
onDragEnd: (details) {
print("----------onDragEnd");
},
),
const SizedBox(height: 200),
//目标控件
DragTarget<bool>(
builder: (BuildContext context, List<dynamic> candidateData,
List<dynamic> rejectedData) {
return _accept
? _buildDraggable(context)
: _buildDragTarget(context);
},
//当 [Draggable] 移动到 [DragTarget] 内时的回调。 返回true松开会触发onAccept onAcceptWithDetails,返回false则不会触发onAccept onAcceptWithDetails
onWillAccept: (bool? value) {
print("----------onWillAccept");
return true;
},
//目标控件接收成功的回调
onAccept: (bool value) {
setState(() {
_accept = value;
});
print("----------onAccept");
},
///用于确定 [DragTarget] 接受信息的签名 包括锚点的位置等。
onAcceptWithDetails: (details) {
print("----------onAcceptWithDetails");
},
// 当 [Draggable] 在 [DragTarget] 内离开时的回调。
onLeave: (bool? value) {
print("----------onLeave");
},
//当 [Draggable] 在 [DragTarget] 内移动时的回调。
onMove: (details) {
print("----------onMove");
},
)
],
),
),
);
}
Widget _buildDraggable(BuildContext context) {
return Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(4),
),
child: const Text(
'Draggable',
style: TextStyle(color: Colors.white, fontSize: 18),
),
);
}
Widget _buildFeedback(BuildContext context) {
return Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(4),
),
child: const Text(
'Feedback',
style: TextStyle(color: Colors.white, fontSize: 18),
),
);
}
Widget _buildDragTarget(BuildContext context) {
return Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Colors.grey,
),
child: Text("DragTarget"),
);
}
}
注意:
details.offset.dy的值包含状态栏和appbar的高度