Android实现图片随手指旋转功能
本文实例为大家分享了Android实现图片随手指旋转功能的具体代码,供大家参考,具体内容如下
在View中进行重绘,主要是通过计算角度及距离来实现。实现类代码如下:
packagecom.example.roatedemo; importjava.util.Calendar; importandroid.content.Context; importandroid.graphics.Bitmap; importandroid.graphics.BitmapFactory; importandroid.graphics.Canvas; importandroid.graphics.Matrix; importandroid.graphics.Paint; importandroid.util.Log; importandroid.view.MotionEvent; importandroid.view.View; publicclassRotateViewextendsView{ privatePaintmPaint=newPaint(); privateBitmapbitmaplittele;//中间不动的图片 privateBitmapbitmapBig;//随手指转动的图片 privateBitmapbitmapOut;//外围不动的图片 //圆心坐标 privatefloatmPointX=0,mPointY=0; privateintflag=0; //半径 privateintmRadius=0; //旋转角度 privateintmAngle=0; privateintbeginAngle=0,currentAngle=0; privateStringTAG="NewView"; intbitMap[]={R.drawable.circle0,R.drawable.circle1,R.drawable.circle2}; intimageIndex=0; booleanisUp=false,isTouch=false; ContextmContext; RotateViewListenerlistener; longbeginTime,endTime; Calendarnow; publicRotateView(Contextcontext,intpx,intpy,intradius,RotateViewListenerlistener){ super(context); mContext=context; this.listener=listener; mPointX=px; mPointY=py; mRadius=radius; bitmaplittele=BitmapFactory.decodeResource(getResources(), R.drawable.a1_pointer).copy(Bitmap.Config.ARGB_8888,true); bitmapBig=BitmapFactory.decodeResource(getResources(),bitMap[0]) .copy(Bitmap.Config.ARGB_8888,true); bitmapOut=BitmapFactory.decodeResource(getResources(), R.drawable.bigcir).copy(Bitmap.Config.ARGB_8888,true); setBackgroundResource(R.drawable.back); Log.e(TAG,"RotateViewBegin"); } @Override publicbooleandispatchTouchEvent(MotionEvente){ switch(e.getAction()&MotionEvent.ACTION_MASK){ caseMotionEvent.ACTION_DOWN: now=Calendar.getInstance(); beginTime=now.getTimeInMillis(); beginAngle=computeCurrentAngle(e.getX(),e.getY()); isUp=false; //如果点击触摸范围在圈外,则不处理 if(getDistance(e.getX(),e.getY())>bitmapOut.getWidth()/2){ isTouch=false; }else{ isTouch=true; } returntrue; caseMotionEvent.ACTION_MOVE: if(!isTouch){ returntrue; } currentAngle=computeCurrentAngle(e.getX(),e.getY()); invalidate(); returntrue; caseMotionEvent.ACTION_UP: isUp=true; if(!isTouch){ returntrue; } now=Calendar.getInstance(); endTime=now.getTimeInMillis(); if(SetClick(e.getX(),e.getY())){ returntrue; } if(mAngle>0){ intcount=mAngle/120+(mAngle%120>60?1:0); imageIndex=(imageIndex+count)%3; }elseif(mAngle<0){ mAngle=-mAngle; intcount=mAngle/120+(mAngle%120>60?1:0); imageIndex=(imageIndex+3-count)%3; } bitmapBig=BitmapFactory.decodeResource(getResources(), bitMap[imageIndex]).copy(Bitmap.Config.ARGB_8888,true); bitmapBig=adjustPhotoRotation(bitmapBig,imageIndex*120); invalidate(); if(mAngle>=60){ listener.onModChange(imageIndex); } returntrue; } returnfalse; } @Override publicvoidonDraw(Canvascanvas){ //Log.i(TAG,"onDraw"); //大圆 drawInCenter(canvas,bitmapOut,mPointX,mPointY,TAG); //外圈 if(isUp){ mAngle=0; }else{ mAngle=currentAngle-beginAngle; } BitmaptempBig=adjustPhotoRotation(bitmapBig,mAngle); //Log.i(TAG,"mAngle:"+mAngle); drawInCenter(canvas,tempBig,mPointX,mPointY+10,TAG); //小圆(中间的圆心) drawInCenter(canvas,bitmaplittele,mPointX,mPointY-10,TAG); } BitmapadjustPhotoRotation(Bitmapbm,finalintorientationDegree){ if(orientationDegree==0){ returnbm; } Matrixm=newMatrix(); m.setRotate(orientationDegree,(float)bm.getWidth()/2, (float)bm.getHeight()/2); try{ Bitmapbm1=Bitmap.createBitmap(bm,0,0,bm.getWidth(), bm.getHeight(),m,true); returnbm1; }catch(OutOfMemoryErrorex){ } returnnull; } privatevoiddrawInCenter(Canvascanvas,Bitmapbitmap,floatleft, floattop,Stringtext){ canvas.drawBitmap(bitmap,left-bitmap.getWidth()/2, top-bitmap.getHeight()/2,null); } //子控件位置改变重新计算角度 privateintcomputeCurrentAngle(floatx,floaty){ //根据圆心坐标计算角度 floatdistance=(float)Math .sqrt(((x-mPointX)*(x-mPointX)+(y-mPointY) *(y-mPointY))); intdegree=(int)(Math.acos((x-mPointX)/distance)*180/Math.PI); if(y10||mAngle<-10){ returnfalse; }elseif(endTime-beginTime>1000){ returnfalse; } if(distance beginAngle){ mod=(imageIndex+3-2)%3; } else{ mod=imageIndex; } //回调到主界面进行处理。 listener.onModClick(mod); } returntrue; } publicinterfaceRotateViewListener{ voidonModClick(intmode); voidonModChange(intmode); } }
Activity中调用代码:
packagecom.example.roatedemo; importcom.example.roatedemo.RotateView.RotateViewListener; importandroid.app.Activity; importandroid.content.Context; importandroid.os.Bundle; importandroid.util.DisplayMetrics; importandroid.util.Log; importandroid.widget.Toast; publicclassMainActivityextendsActivityimplementsRotateViewListener{ RotateViewrotateView; StringTAG="MainActivity"; ContextmContext; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); mContext=this; intheight,width; DisplayMetricsdisplayMetrics=newDisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); height=displayMetrics.heightPixels; width=displayMetrics.widthPixels; Log.i(TAG,"height:"+height); Log.i(TAG,"width:"+width); rotateView=newRotateView(getApplicationContext(),width/2,height/3,150,this); setContentView(rotateView); } @Override publicvoidonModClick(intmode){ String[]clickStrings=newString[]{"1被点击","2被点击","3被点击"}; Toast.makeText(mContext,clickStrings[mode],0).show(); } @Override publicvoidonModChange(intmode){ String[]clickStrings=newString[]{"切换到1","切换到2","切换到3"}; Toast.makeText(mContext,clickStrings[mode],0).show(); } }
布局文件默认即可。
除了实现图片旋转,还实现将图片切成3部分,每部分120度,每转动120度切换一个模式,点击每个部分均有响应事件回调到主界面。涉及保密,图片不给在此给出。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。