旋转矩形框

来源:互联网 发布:电视节目片头制作软件 编辑:程序博客网 时间:2024/06/10 05:09

MotionEvent中getAction( )与getActionMasked( )的区别:

getAction( )得到的值是由触控点index + 触控事件 构成;

getActionMasked( )得到的值仅由 触控事件 构成.


onTouchEvent(MotionEvent event)的实现:

public boolean onTouchEvent(MotionEvent event){        PointF current=new PointF(event.getX(),event.getY());        String action="";        switch(event.getActionMasked()){            case MotionEvent.ACTION_DOWN:                action="ACTION_DOWN";                mCurrentBox=new Box(current);                mBoxen.add(mCurrentBox);                pointer1=event.getPointerId(event.getActionIndex()); //当第一个手指触摸到屏幕后,记录第一个触控点的ID                break;                                                                           case MotionEvent.ACTION_POINTER_DOWN:                action="ACTION_POINTER_DOWN";                pointer2=event.getPointerId(event.getActionIndex()); //当第二个手指触摸到屏幕后,记录第二个触控点的ID                fx=event.getX(event.findPointerIndex(pointer1));                fy=event.getY(event.findPointerIndex(pointer1));                sx=event.getX(event.findPointerIndex(pointer2));                sy=event.getY(event.findPointerIndex(pointer2));     //得到第一,第二个触控点的横,纵坐标                mCurrentBox=null;                break;            case MotionEvent.ACTION_UP:                action="ACTION_UP";                pointer1=-1;                mCurrentBox=null;                break;            case MotionEvent.ACTION_POINTER_UP:                action="ACTION_POINTER_UP";                pointer2=-1;                break;            case MotionEvent.ACTION_MOVE:                action="ACTION_MOVE";                if(pointer1!=removed && pointer2!=removed){                    nfx=event.getX(event.findPointerIndex(pointer1));                    nfy=event.getY(event.findPointerIndex(pointer1));                    nsx=event.getX(event.findPointerIndex(pointer2));                    nsy=event.getY(event.findPointerIndex(pointer2));     //得到手指移动后第一,第二个触控点的横,纵坐标                    mAngle=angleBetweenLines(fx,fy,sx,sy,nfx,nfy,nsx,nsy);  //计算移动前后的角度差值                }                if(mCurrentBox!=null && pointer2==removed){                    mCurrentBox.setCurrent(current);                }                invalidate();                break;            case MotionEvent.ACTION_CANCEL:                action="ACTION_CANCEL";                mCurrentBox=null;                pointer1=-1;                pointer2=-1;                break;            default:;        }        Log.d(TAG,"action "+action+" at x="+current.x+" y="+current.y);        return true;    }

其中注意ACTION_DOWN与ACTION_POINTER_DOWN的区别,ACTION_DOWN是在第一根手指触摸屏幕时产生的事件,而ACTION_POINTER_DOWN是在多点触控下(也就是已经有手指触摸在屏幕上),又有一根手指触摸屏幕产生的事件。

上面代码中angleBetweenLines( )方法的实现:

public float angleBetweenLines(float fx, float fy, float sx, float sy, float nfx, float nfy, float nsx, float nsy){        float radian1=(float)Math.atan2(fy-sy,fx-sx);        float radian2=(float)Math.atan2(nfy-nsy,nfx-nsx);        float angle=(float)(Math.toDegrees(radian2-radian1)%360);        if(angle<0){            angle+=360;        }        return angle;    }
利用反三角函数atan2( )计算出对应斜率的弧度,移动前后的弧度值相减,并转换为角度值。

onDraw( Canvas)的实现:

public void onDraw(Canvas canvas){        canvas.drawPaint(mBackgroundPaint);        for(Box box:mBoxen){            if(mAngle!=null){             //mAngle存储的是angleBetweenLines方法中计算出的角度值                canvas.rotate(mAngle);     //旋转画布                mAngle=null;            }            float leftX=Math.min(box.getCurrent().x,box.getOrigin().x);            float leftY=Math.min(box.getCurrent().y,box.getOrigin().y);            float rightX=Math.max(box.getCurrent().x,box.getOrigin().x);            float rightY=Math.max(box.getCurrent().y,box.getOrigin().y);            canvas.drawRect(leftX,leftY,rightX,rightY,mBoxPaint);        }    }

效果:


demo地址:https://github.com/zycoJamie/Rotate-Rectangle




阅读全文
0 0