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(distancebeginAngle){
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度切换一个模式,点击每个部分均有响应事件回调到主界面。涉及保密,图片不给在此给出。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。