int len = mCropPoints.length;
for (int i = 0; i < len; i++){
// 为了避免极端情况,
// 采用 ( 坐标 + 距离的一半 ) 的方式
mEdgeMidPoints[i].set(mCropPoints[i].x + (mCropPoints[(i+1)%len].x - mCropPoints[i].x)/2,
mCropPoints[i].y + (mCropPoints[(i+1)%len].y - mCropPoints[i].y)/2);
}
}
2, 拖动
拖动分 2 种情况,角点拖拽,中点平移
8 个类型, 4 个角点拖拽,4 个中点平移
enum DragPointType{
LEFT_TOP,
RIGHT_TOP,
RIGHT_BOTTOM,
LEFT_BOTTOM,
TOP,
RIGHT,
BOTTOM,
LEFT;
// 判断是角点拖拽,不是中点平移
public static boolean isEdgePoint(DragPointType type){
return type == TOP || type == RIGHT || type == BOTTOM || type == LEFT;
}
}
移动的处理
@Override
public boolean onTouchEvent(MotionEvent event) {
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,中点平移
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了,我自己手头上整理的资料均和上面的答案可免费分享,需要这些资料和答案的朋友,可以点击这里免费领取。
文章篇幅有限,所以只是把题目列出来了,我自己手头上整理的资料均和上面的答案可免费分享,需要这些资料和答案的朋友,可以点击这里免费领取。
[外链图片转存中…(img-bVdjIrdr-1711324637994)]
[外链图片转存中…(img-7fi87kPc-1711324637995)]