怎么在Android中实现一个图片随手指旋转功能

发布时间:2021-02-22 17:31:52 作者:戴恩恩
来源:亿速云 阅读:185

这篇文章主要为大家详细介绍了怎么在Android中实现一个图片随手指旋转功能,文中示例代码介绍的非常详细,具有一定的参考价值,发现的小伙伴们可以参考一下:

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

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中调用代码:

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();  
  } 
 
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。

推荐阅读:
  1. 怎么在Android中利用贝塞尔曲线实现手指轨迹
  2. 怎么在Android中实现一个图片点击切换功能

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android

上一篇:如何将http转换成https

下一篇:如何在Android中利用View实现一个自动转圈功能

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》