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