Android实现图片随手指旋转功能

2020-11-05 14:45:13 浏览数 (1)

本文实例为大家分享了Android实现图片随手指旋转功能的具体代码,供大家参考,具体内容如下

在View中进行重绘,主要是通过计算角度及距离来实现。实现类代码如下:

代码语言:javascript复制
package com.example.roatedemo; 
import java.util.Calendar; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
public class RotateView extends View { 
private Paint mPaint = new Paint(); 
private Bitmap bitmaplittele;//中间不动的图片 
private Bitmap bitmapBig;//随手指转动的图片 
private Bitmap bitmapOut;//外围不动的图片 
// 圆心坐标 
private float mPointX = 0, mPointY = 0; 
private int flag = 0; 
// 半径 
private int mRadius = 0; 
// 旋转角度 
private int mAngle = 0; 
private int beginAngle = 0, currentAngle = 0; 
private String TAG = "NewView"; 
int bitMap[] = { R.drawable.circle0, R.drawable.circle1, R.drawable.circle2 }; 
int imageIndex = 0; 
boolean isUp = false,isTouch=false; 
Context mContext; 
RotateViewListener listener; 
long beginTime,endTime; 
Calendar now; 
public RotateView(Context context, int px, int py, int radius,RotateViewListener listener) { 
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 
public boolean dispatchTouchEvent(MotionEvent e) { 
switch (e.getAction() & MotionEvent.ACTION_MASK) { 
case MotionEvent.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; 
} 
return true; 
case MotionEvent.ACTION_MOVE: 
if (!isTouch) { 
return true; 
} 
currentAngle = computeCurrentAngle(e.getX(), e.getY()); 
invalidate(); 
return true; 
case MotionEvent.ACTION_UP: 
isUp = true; 
if (!isTouch) { 
return true; 
} 
now = Calendar.getInstance(); 
endTime = now.getTimeInMillis(); 
if (SetClick(e.getX(), e.getY())) { 
return true; 
}       
if (mAngle   0) { 
int count = mAngle / 120   (mAngle % 120   60 ? 1 : 0); 
imageIndex = (imageIndex   count) % 3; 
} else if (mAngle < 0) { 
mAngle = -mAngle; 
int count = 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); 
}       
return true; 
} 
return false; 
} 
@Override 
public void onDraw(Canvas canvas) { 
// Log.i(TAG, "onDraw"); 
// 大圆 
drawInCenter(canvas, bitmapOut, mPointX, mPointY, TAG); 
// 外圈 
if (isUp) { 
mAngle = 0; 
} else { 
mAngle = currentAngle - beginAngle; 
} 
Bitmap tempBig = adjustPhotoRotation(bitmapBig, mAngle); 
// Log.i(TAG, "mAngle:" mAngle); 
drawInCenter(canvas, tempBig, mPointX, mPointY   10, TAG); 
// 小圆(中间的圆心) 
drawInCenter(canvas, bitmaplittele, mPointX, mPointY - 10, TAG); 
} 
Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) { 
if (orientationDegree == 0) { 
return bm; 
} 
Matrix m = new Matrix(); 
m.setRotate(orientationDegree, (float) bm.getWidth() / 2, 
(float) bm.getHeight() / 2); 
try { 
Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), 
bm.getHeight(), m, true); 
return bm1; 
} catch (OutOfMemoryError ex) { 
} 
return null; 
} 
private void drawInCenter(Canvas canvas, Bitmap bitmap, float left, 
float top, String text) { 
canvas.drawBitmap(bitmap, left - bitmap.getWidth() / 2, 
top - bitmap.getHeight() / 2, null); 
} 
// 子控件位置改变重新计算角度 
private int computeCurrentAngle(float x, float y) { 
// 根据圆心坐标计算角度 
float distance = (float) Math 
.sqrt(((x - mPointX) * (x - mPointX)   (y - mPointY) 
* (y - mPointY))); 
int degree = (int) (Math.acos((x - mPointX) / distance) * 180 / Math.PI); 
if (y < mPointY) { 
degree = -degree; 
} 
if (degree < 0) { 
degree  = 360; 
} 
// Log.i("RoundSpinView", "x:"   x   ",y:"   y   ",degree:"   degree); 
return degree; 
} 
// 获取距离圆心的距离 
private float getDistance(float x, float y) { 
// 根据圆心坐标计算角度 
float distance = (float) Math 
.sqrt(((x - mPointX) * (x - mPointX)   (y - mPointY) 
* (y - mPointY))); 
return distance; 
} 
//点击 
private boolean SetClick(float x, float y) { 
float distance = getDistance(x, y); 
if (mAngle 10||mAngle<-10) { 
return false; 
}else if(endTime-beginTime 1000){ 
return false; 
} 
if (distance < bitmapBig.getWidth() / 2) { 
int mod = 0; 
if (beginAngle < 90 || 330 < beginAngle) { 
mod = (imageIndex 3-1)%3;               
} 
else if (90 < beginAngle && 210   beginAngle) { 
mod = (imageIndex 3-2)%3;         
} 
else{ 
mod = imageIndex;         
} 
//回调到主界面进行处理。 
listener.onModClick(mod); 
} 
return true; 
} 
public interface RotateViewListener {     
void onModClick(int mode); 
void onModChange(int mode); 
} 
}

Activity中调用代码:

代码语言:javascript复制
package com.example.roatedemo; 
import com.example.roatedemo.RotateView.RotateViewListener; 
import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.util.Log; 
import android.widget.Toast; 
public class MainActivity extends Activity implements RotateViewListener{ 
RotateView rotateView; 
String TAG="MainActivity"; 
Context mContext; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
mContext = this; 
int height,width; 
DisplayMetrics displayMetrics = new DisplayMetrics();  
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 
height = displayMetrics.heightPixels; 
width = displayMetrics.widthPixels; 
Log.i(TAG, "height:" height); 
Log.i(TAG, "width:" width); 
rotateView = new RotateView(getApplicationContext(), width/2, height/3, 150,this); 
setContentView(rotateView); 
} 
@Override 
public void onModClick(int mode) { 
String[] clickStrings = new String[] { "1被点击", "2被点击","3被点击" }; 
Toast.makeText(mContext, clickStrings[mode], 0).show(); 
} 
@Override 
public void onModChange(int mode) { 
String[] clickStrings = new String[] { "切换到1", "切换到2","切换到3" }; 
Toast.makeText(mContext, clickStrings[mode], 0).show();  
} 
} 

布局文件默认即可。

除了实现图片旋转,还实现将图片切成3部分,每部分120度,每转动120度切换一个模式,点击每个部分均有响应事件回调到主界面。涉及保密,图片不给在此给出。

以上就是本文的全部内容,希望对大家的学习有所帮助。

0 人点赞