手势触摸 围绕圆画线 Android
效果: import java.util.ArrayList; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class RotateView extends View { float Degree; float mCenterY = 150; float mCenterX = 150; float circlueradius2; ArrayList<PaintLine> mArryPaintLine; boolean mBooleanMove = true; double postion; float moveX; float moveY; boolean mNewLine = false; boolean rotateDirect = true; private float rotateAngle; Handler mHandler; Thread MyInvalidateThread; boolean mThreadIsStart = false; static Context mContext; public RotateView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mArryPaintLine = new ArrayList<PaintLine>(); mHandler = new Handler(){ @Override public void handleMessage(Message msg) { //super.handleMessage(msg); if (msg.what==1) { Log.d("msg", ""+msg.what); RotateView.this.postInvalidate(); Log.i("mArryPaintLine.size", ""+mArryPaintLine.size()); for(int i=0;i<mArryPaintLine.size();i++){ if(mArryPaintLine.get(i).index<0){ mArryPaintLine.remove(i); i=i-1; } } } } }; MyInvalidateThread =new Thread() { @Override public void run() { Log.i("runable:", "runable::"); Message msg = mHandler.obtainMessage(); msg.what = 1; mThreadIsStart = true; while(mArryPaintLine.size()>0){ try { MyInvalidateThread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(mArryPaintLine.size()!=0){ mHandler.sendEmptyMessage(msg.what); } } } }; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); if(mArryPaintLine!=null){ for (int i = 0; i < mArryPaintLine.size(); i++) { // Log.i("mArryPaintLine", "mArryPaintLine"+mArryPaintLine.size()); PaintLine _paintLine =mArryPaintLine.get(i);//mArryPaintLine.get(0); canvas.drawLine(_paintLine.StartX, _paintLine.StartY, _paintLine.EndX, _paintLine.EndY, _paintLine.paint); } } canvas.restore(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.i("down", "down"); moveX = x; moveY = y; this.postInvalidate(); return true; case MotionEvent.ACTION_MOVE: Log.i("move", "move"); mBooleanMove = true; Degree = (float) Math.toDegrees(Math.atan2(mCenterY - y, mCenterX - x)); Log.i("Degree:", ""+(Degree+180)); Degree = ((int)(Degree+2.5)/5)*5; double thet1 = 0;// 角度计算 double thet2 = 0; if (x - mCenterX != 0) { thet1 = Math.atan((y - mCenterY) / (x - mCenterX)); } if (moveX - mCenterX != 0) { thet2 = Math.atan((moveY - mCenterY) / (moveX - mCenterX)); } thet1 = Math.toDegrees(thet1); thet2 = Math.toDegrees(thet2); double delAngle = 0; if (thet1 > 0 && thet2 < 0 || thet2 > 0 && thet1 < 0) { delAngle = (thet1 + thet2); } else { delAngle = (thet1 - thet2); } // 角度判断 postion += delAngle; if(postion>0){ rotateDirect = true; }else if(postion<0){ rotateDirect = false; } if (postion > 30) { postion = 0; } else if (postion < -30) { postion = 0; } // 累加 rotateAngle += delAngle; rotateAngle %= 360; /*if(Math.abs(delAngle)<=20&(Math.abs(delAngle)>5)){ for(int i =0;i< delAngle/5;i++){ Degree+=5; calculate(Degree+180); } }else if(Math.abs(delAngle)>20){ for (int i =0;i<mArryPaintLine.size(); i++) { mArryPaintLine.get(i).interrupt(); mArryPaintLine.remove(i); } calculate(Degree+180); }else {*/ calculate(Degree+180); // } //calculate(Degree+180); //PaintLine _paintLine = calculate(Degree+180); //_paintLine.start(); for (int i =0;i<mArryPaintLine.size(); i++) { //PaintLine _paintLine = mArryPaintLine.get(i); if(mArryPaintLine.get(i).isAlive()==false&mArryPaintLine.get(i).index==180){ mArryPaintLine.get(i).start(); }else if(mArryPaintLine.get(i).index==0){ //_paintLine = null; mArryPaintLine.get(i).interrupt(); mArryPaintLine.remove(i); } } this.postInvalidate(); return true; case MotionEvent.ACTION_UP: Log.i("up", "up"); mBooleanMove = false; //for (int i =0;i<mArryPaintLine.size();) { //PaintLine _paintLineT = mArryPaintLine.get(i); /*if(_paintLineT.isAlive()==false&mArryPaintLine.get(i).index==180){ _paintLineT.start(); }else if(_paintLineT.index==0){ //_paintLineT = null; mArryPaintLine.get(i).interrupt(); mArryPaintLine.remove(i); }*/ if(mArryPaintLine.size()!=0&!MyInvalidateThread.isAlive()){ /* Message msg = mHandler.obtainMessage(); msg.what = 1; mHandler.sendEmptyMessage(msg.what);*/ // MyInvalidateThread = null; MyInvalidateThread =new Thread() { @Override public void run() { Log.i("runable:", "runable::"); Message msg = mHandler.obtainMessage(); msg.what = 1; mThreadIsStart = true; while(mArryPaintLine.size()>0){ try { MyInvalidateThread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(mArryPaintLine.size()!=0){ mHandler.sendEmptyMessage(msg.what); } } } }; MyInvalidateThread.start(); /*}else if(mThreadIsStart==true){ MyInvalidateThread.resume();*/ } // } //this.postInvalidate(); return true; case MotionEvent.ACTION_CANCEL: Log.i("cancel", "cancel"); return true; default: break; } Log.i("return", "return"); return super.onTouchEvent(event); } /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } public void calculate(float pCirclueAngle){ Log.i("pCirclueAngle:", ""+pCirclueAngle); float circlueradius = 150; /*if(((int)pCirclueAngle%4)==0){ mNewLine = true; }else { mNewLine = false; }*/ float CirclueAngleFirst = pCirclueAngle; float StartX ; float StartY ; float EndX ; float EndY ; //float CirclueAngleFirst = pCirclueAngle; StartY = (float) (mCenterY + circlueradius * Math.sin(CirclueAngleFirst * (Math.PI /180))); StartX = (float) (mCenterX +circlueradius * Math.cos(CirclueAngleFirst * (Math.PI /180))); circlueradius2 = circlueradius-dip2px(mContext,15); EndY = (float) (mCenterY + circlueradius2 * Math.sin(CirclueAngleFirst * (Math.PI / 180))); EndX =(float) ( mCenterX + circlueradius2 * Math.cos(CirclueAngleFirst * (Math.PI / 180))); //if(mNewLine){ PaintLine mPaintLine = new PaintLine(StartX,StartY,EndX,EndY); mArryPaintLine.add(mPaintLine); //mPaintLine.start(); //} } } class PaintLine extends Thread{ float paintStrokeWidth; Paint paint; float StartX; float StartY; float EndX; float EndY; int index = 180; boolean mIsRun = false; public PaintLine(float pStartX,float pStartY,float pEndX,float pEndY){ paint = new Paint(); paintStrokeWidth = dip2px(RotateView.mContext,3); paint.setColor(Color.BLUE); paint.setStrokeWidth(paintStrokeWidth); paint.setAntiAlias(true); StartX = pStartX; StartY = pStartY; EndX = pEndX; EndY = pEndY; } /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override public void run() { mIsRun = true; while(index>=0){ this.paint.setAlpha(index); try { PaintLine.this.sleep(25); index = index-9; } catch (InterruptedException e) { e.printStackTrace(); } } } }