int action = event.getAction(); boolean handle = true; switch (action) { case MotionEvent.ACTION_DOWN: // 识别到,当前点 mDraggingPoint = getNearbyPoint(event); if (mDraggingPoint == null) { handle = false; } break; case MotionEvent.ACTION_MOVE: // 移动 toImagePointSize(mDraggingPoint, event); break; case MotionEvent.ACTION_UP: // 手指抬起, // 操作取消 mDraggingPoint = null; break; } // 绘制 // 更新完位置后,刷新绘制 invalidate(); return handle || super.onTouchEvent(event); }
识别到,当前点
private Point getNearbyPoint(MotionEvent event) { // 判断 4 个角点,可用 if (checkPoints(mCropPoints)) { for (Point p : mCropPoints) { // 找出当前的点 if (isTouchPoint(p, event)) return p; } } // 判断 4 个中点可用 if (checkPoints(mEdgeMidPoints)) { for (Point p : mEdgeMidPoints){ // 找出当前的点 if (isTouchPoint(p, event)) return p; } } return null; }
找出当前的点,的方法
private static final float TOUCH_POINT_CATCH_DISTANCE = 15;
private boolean isTouchPoint(Point p, MotionEvent event){ float x = event.getX(); float y = event.getY(); float px = getViewPointX§; float py = getViewPointY§; double distance = Math.sqrt(Math.pow(x - px, 2) + Math.pow(y - py, 2));
// 也就是,判断距离 if (distance < dp2px(TOUCH_POINT_CATCH_DISTANCE)) { return true; } return false; }
2.1 ,角点拖拽
先介绍 4 个角点拖拽
private void toImagePointSize(Point dragPoint, MotionEvent event) { if (dragPoint == null) { return; } // 找出当前移动类型, // 是角点拖拽,还是中点平移 DragPointType pointType = getPointType(dragPoint);
int x = (int) ((Math.min(Math.max(event.getX(), mActLeft), mActLeft + mActWidth) - mActLeft) / mScaleX); int y = (int) ((Math.min(Math.max(event.getY(), mActTop), mActTop + mActHeight) - mActTop) / mScaleY);
// 判断可以移动 // …
if (DragPointType.isEdgePoint(pointType)){ // … // 中点平移 } else { // 角点拖拽 // 实现很简单, // 更新就好了 dragPoint.y = y; dragPoint.x = x; } }
找出当前移动类型,
是角点拖拽,还是中点平移
// 拿采集的点,找出对应的类型 private DragPointType getPointType(Point dragPoint){ if (dragPoint == null) return null;
DragPointType type; // 看,是不是顶点 / 角点 if (checkPoints(mCropPoints)) { for (int i = 0; i < mCropPoints.length; i++) { if (dragPoint == mCropPoints[i]) { // 找到了,直接返回 type = DragPointType.values()[i]; return type; } } } // 看,是不是中点 if (checkPoints(mEdgeMidPoints)) { for (int i = 0; i < mEdgeMidPoints.length; i++){ if (dragPoint == mEdgeMidPoints[i]){ // 找到了,直接返回 type = DragPointType.values()[4+i]; return type; } } } return null; }
2.2,中点平移
private void toImagePointSize(Point dragPoint, MotionEvent event) { if (dragPoint == null) { return; }
DragPointType pointType = getPointType(dragPoint);
int x = // … int y = // …
// 判断可以移动 // …
if (DragPointType.isEdgePoint(pointType)){ // 中点平移, // 拿到的是,一个偏移向量 int xoff = x - dragPoint.x; int yoff = y - dragPoint.y; moveEdge(pointType, xoff, yoff); } else { // 角点拖拽 // … } }
拿到偏移向量,修改对应的两个顶点的坐标
private void moveEdge(DragPointType type, int xoff, int yoff){ switch (type){ case TOP: // 这边的平移,比较简单 // 找到中点,旁边的两个焦点 // 再移动位置 movePoint(mCropPoints[P_LT], 0, yoff); movePoint(mCropPoints[P_RT], 0, yoff); break;
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整资料开源分享
case RIGHT: // 右移处理 movePoint(mCropPoints[P_RT], xoff, 0); movePoint(mCropPoints[P_RB], xoff, 0); break; case BOTTOM: // 下移处理 // … case LEFT: // 左移处理 // … default: break; } }
简单的平移代码
拿到偏移向量, 修改坐标,完事
private void movePoint(Point point, int xoff, int yoff){ if (point == null) return; int x = point.x + xoff; int y = point.y + yoff; // 检查边界 if (x < 0 || x > getDrawable().getIntrinsicWidth()) return; if (y < 0 || y > getDrawable().getIntrinsicHeight()) return; point.x = x; point.y = y; }
中点平移增强
这里的中点平移,拿到平移向量后,
|