Flutter实现控件拖动
核心Api
控件拖动 主要需要两块实现,一个是检查 点击事件、拖动事件 ,一个是实现拖动
检查交互事件可以通过 GestureDetector 实现
拖动效果可以通过Transform.translate 实现
自定义painter
为了体现拖动效果,用一个自定义的paint实现,设计是正常情况下显示为红色圆球,拖动时显示为绿色,松手后又恢复为红色,这里用到了 CustomPainter 实现
View整体代码如下
import 'package:flutter/material.dart';
import 'dart:math';
class TouchMoveView extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return TouchMoveState();
}
}
class TouchMoveState extends State<TouchMoveView> {
TouchMovePainter painter;
//静止状态下的offset
Offset idleOffset=Offset(0, 0);
//本次移动的offset
Offset moveOffset=Offset(0, 0);
//最后一次down事件的offset
Offset lastStartOffset=Offset(0, 0);
@override
void initState() {
painter = TouchMovePainter();
super.initState();
}
@override
Widget build(BuildContext context) {
return Transform.translate(
offset: moveOffset,
child: Container(
height: 50,
width: 50,
child: GestureDetector(
onPanStart: (detail) {
setState(() {
lastStartOffset=detail.globalPosition;
painter=TouchMovePainter();
painter.painterColor = Colors.green;
});
},
onPanUpdate: (detail){
setState(() {
moveOffset=detail.globalPosition-lastStartOffset+idleOffset;
moveOffset=Offset(max(0, moveOffset.dx), max(0, moveOffset.dy));
});
},
onPanEnd: (detail) {
setState(() {
painter=TouchMovePainter();
painter.painterColor = Colors.red;
idleOffset=moveOffset*1;
});
},
child: CustomPaint(
painter: painter,
),
),
));
}
}
class TouchMovePainter extends CustomPainter {
var painter = Paint();
var painterColor = Colors.red;
@override
void paint(Canvas canvas, Size size) {
painter.color = painterColor;
canvas.drawCircle(Offset(size.width / 2, size.height / 2),
min(size.height, size.width) / 2, painter);
}
@override
bool shouldRepaint(TouchMovePainter oldDelegate) {
return oldDelegate.painterColor!=painterColor;
}
}