Flutter 仿qq消息拖拽效果通过自定义view实现,效果如下
拖拽.gif
细节.png
- 如果要实现最终的效果,首先绘制拖拽连接处的线(很长矩形).
- 手指拖拽时,为了保证矩形宽度不变,计算矩形四个点的动态坐标,
- 通过Path连接,将上下两边用贝塞尔曲线替换.
- 最后两边绘制圆形,隐藏矩形尖角.
var angleA = atan((during.dx - end.dx) / (end.dy - during.dy));
var temp_dx = cos(angleA) * lineWidth;
var temp_dy = sin(angleA) * lineWidth;
var firstControlPoint = Offset(end.dx + (during.dx - end.dx) / 2, during.dy + (end.dy - during.dy) / 2);
var firstPoint = Offset(during.dx + temp_dx, during.dy + temp_dy);
var secondPoint = Offset(end.dx - temp_dx * ratio, end.dy - temp_dy * ratio);
/**
p1 p3
|------------------------|
| |
| |
|------------------------|
p2 p4
*/
// 原点 -> p1
path.moveTo(end.dx - temp_dx * ratio, end.dy - temp_dy * ratio);
// p1 -> p2
path.lineTo(end.dx + temp_dx * ratio, end.dy + temp_dy * ratio);
// p2 -> p4
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, firstPoint.dx, firstPoint.dy);
// p4 -> p3
path.lineTo(during.dx - temp_dx, during.dy - temp_dy);
// p3 -> p1
path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy, secondPoint.dx, secondPoint.dy);
canvas.drawPath(path, paint);
canvas.drawCircle(end, lineWidth * ratio, paint);
canvas.drawCircle(during, lineWidth, paint);
如有问题欢迎留言指正.
网友评论