温馨提示×

温馨提示×

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

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

如何在Android项目中使用ImageView

发布时间:2020-11-26 16:10:48 来源:亿速云 阅读:228 作者:Leah 栏目:移动开发

这期内容当中小编将会给大家带来有关如何在Android项目中使用ImageView,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

首先创建一个叫MatrixImageView的类去继承ImageView,然后重写其构造方法:

public class MatrixImageView2 extends ImageView {  public MatrixImageView2(Context context, AttributeSet attrs) {   super(context, attrs);   initView();  } }

然后我们需要定义几种当前view的状态:
MODE_NONE(初始状态);
MODE_DRAG(拖拽状态);
MODE_ZOOM(两个手指缩放状态)

public class MatrixImageView2 extends ImageView {  private static final int MODE_NONE = 190;  private static final int MODE_DRAG = 468;  private static final int MODE_ZOOM = 685;  ..... }

我们对ImageView做旋转、缩放、位移等操作主要是用到ImageView的这个方法:

 /**   * Adds a transformation {@link Matrix} that is applied   * to the view's drawable when it is drawn. Allows custom scaling,   * translation, and perspective distortion.   *   * @param matrix the transformation parameters in matrix form   */  public void setImageMatrix(Matrix matrix) {   // collapse null and identity to just null   if (matrix != null && matrix.isIdentity()) {    matrix = null;   }   // don't invalidate unless we're actually changing our matrix   if (matrix == null && !mMatrix.isIdentity() ||     matrix != null && !mMatrix.equals(matrix)) {    mMatrix.set(matrix);    configureBounds();    invalidate();   }  }

利用的是Matrix这个类(对这个类不懂的童鞋自己去查资料哈~),然后通过监听我们的onTouchEvent方法获取当前手势操作,然后对matrix进行相应操作,改变图片的状态。

代码比较短,而且我每行都注释了,我就直接给代码了:

MatrixImageView.java:

package com.leo.gestureimageview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.widget.ImageView; public class MatrixImageView2 extends ImageView {  private static final int MODE_NONE = 190;  private static final int MODE_DRAG = 468;  private static final int MODE_ZOOM = 685;  //当前mode  private int mode;  //手指按下时候的坐标  private float startX, startY;  //两个手指中间点的位置  private float midX, midY;  //当前imageview的matirx对象,以前imageview的matrix对象  private Matrix currMatrix, savedMatrix;  //之前图片的旋转角度  private float preRotate;  //之间两个手指之间的距离  private float preSpacing;  public MatrixImageView2(Context context, AttributeSet attrs) {   super(context, attrs);   initView();  }  private void initView() {   //初始化模式为初始状态   mode = MODE_NONE;   currMatrix = new Matrix();   savedMatrix = new Matrix();   DisplayMetrics dm = getResources().getDisplayMetrics();   //给ImageView设置一张图片(此处为了测试直接在imageview里面设置了一张测试图片)   Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);   bitmap = Bitmap.createScaledBitmap(bitmap, dm.widthPixels, dm.heightPixels, true);   setImageBitmap(bitmap);  }  @Override  public boolean onTouchEvent(MotionEvent event) {   //多点触碰如果需要监听ACTION_POINTER_DOWN等操作的时候,必须用event.getAction() & MotionEvent.ACTION_MASK   //而不是直接的event.getAction();   switch (event.getAction() & MotionEvent.ACTION_MASK) {    //当一个手指按下的时候    case MotionEvent.ACTION_DOWN:     //保存当前imageview的matrix对象     savedMatrix.set(currMatrix);     //记录手指开始的坐标     startX = event.getX();     startY = event.getY();     //此时的状态为拖拽状态     mode = MODE_DRAG;     break;    //当两个手指按下的时候(我们先不考虑很多个的情况哈,能力有限~!)    case MotionEvent.ACTION_POINTER_DOWN:     //计算两个手指之间的距离并保存起来     preSpacing = calSpacing(event);     //如果两个手指之间的距离大于我们指定的一个值后(改变状态为缩放)     if (preSpacing > 10f) {      savedMatrix.set(currMatrix);      mode = MODE_ZOOM;      //记录下缩放的中间坐标值      midX = (event.getX(0) + event.getX(1)) / 2;      midY = (event.getY(0) + event.getY(1)) / 2;     }     //根据两个手指的位置计算出当前角度并保存     preRotate = calRotate(event);     break;    //当手指移动的时候    case MotionEvent.ACTION_MOVE:     //如果之前给的状态为拖拽状态的时候     if (mode == MODE_DRAG) {      //首先把之前的matrix的状态赋给当前的matrix对象      currMatrix.set(savedMatrix);      //算出手指移动的距离      float dx = event.getX() - startX;      float dy = event.getY() - startY;      //把手指移动的距离设置给matrix对象      currMatrix.postTranslate(dx, dy);      //当状态为放大状态的时候,并且有两个手指按下的时候     } else if (mode == MODE_ZOOM && event.getPointerCount() == 2) {      //首先把之前的matrix的状态赋给当前的matrix对象      currMatrix.set(savedMatrix);      //计算出此时两个手指之间的距离      float spacing = calSpacing(event);      //如果此时两手指之间的距离大于我们给定的值      if (spacing > 10f) {       //此时两手指距离/第二个手指刚按下时两手指的距离       float scale = spacing / preSpacing;       //把算出的缩放值给当前matrix对象,(缩放中心点为之前算出的mid)       currMatrix.postScale(scale, scale, midX, midY);      }      //根据两手指位置算出此时的旋转角度      float rotate = calRotate(event);      if (rotate != preRotate) {       //算出此时需要旋转的角度       rotate = rotate - preRotate;       //开始旋转图片       currMatrix.postRotate(rotate, getMeasuredWidth() / 2, getMeasuredHeight() / 2);      }     }     break;   }   //最后记得把当前的matrix对象给imageview   setImageMatrix(currMatrix);   return true;  }  /**   * 根据两手指的位置算出角度   * 勾股定理 tan0=x(两手指横坐标距离)/y(两手指纵坐标距离);   * @param event   * @return   */  private float calRotate(MotionEvent event) {   double x = event.getX(0) - event.getX(1);   double y = event.getY(0) - event.getY(1);   double radius = Math.atan2(y, x);   return (float) Math.toDegrees(radius);  }  /**   * 两个点距离公式为d*d=(x1-x0)的平方+(y1-y0)的平方   * @param event   * @return   */  private float calSpacing(MotionEvent event) {   float x = event.getX(0) - event.getX(1);   float y = event.getY(0) - event.getY(1);   return (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));  } }

然后添加我们的布局文件:

 <com.leo.gestureimageview.MatrixImageView   android:layout_width="match_parent"   android:layout_height="match_parent"   android:scaleType="matrix"   android:src="@mipmap/test"   />

最后运行代码:

如何在Android项目中使用ImageView

好了,虽说我们是实现了我们的手势imageview的基本功能,但是如果要处理那种多点(>两个手指)触碰,还有一些复杂的操作的时候,我们的onTouchEvent里面写的代码可能就不止这么一点了(还是有点复杂的,考虑的因素太多),但如果可以把某个事件的处理单独拿出去分成很多个分支的话,还会这么复杂么?? 如果说我们的代码可以像下面这样的话,你是不是觉得很爽呢?

package com.leo.gestureimageview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.widget.ImageView; import com.leo.gestureimageview.GestureDetectors.MoveGestureDetector; import com.leo.gestureimageview.GestureDetectors.RotateGestureDetector; public class MatrixImageView2 extends ImageView {  private Matrix mMatrix = new Matrix();  private float mScaleFactor =1f;  private float mRotationDegrees = 0.f;  private float mFocusX = 0.f;  private float mFocusY = 0.f;  private ScaleGestureDetector mScaleDetector;  private RotateGestureDetector mRotateDetector;  private MoveGestureDetector mMoveDetector;  public MatrixImageView2(Context context, AttributeSet attrs) {  super(context, attrs);  initView();  }  private void initView() {  //初始化模式为初始状态  DisplayMetrics dm = getResources().getDisplayMetrics();  //给ImageView设置一张图片(此处为了测试直接在imageview里面设置了一张测试图片)  Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);  bitmap = Bitmap.createScaledBitmap(bitmap, dm.widthPixels, dm.heightPixels, true);  setImageBitmap(bitmap);  mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());  mRotateDetector = new RotateGestureDetector(getContext(), new RotateListener());  mMoveDetector = new MoveGestureDetector(getContext(), new MoveListener());  mFocusX = dm.widthPixels/2f;  mFocusY = dm.heightPixels/2f;  }  @Override  public boolean onTouchEvent(MotionEvent event) {  mScaleDetector.onTouchEvent(event);  mRotateDetector.onTouchEvent(event);  mMoveDetector.onTouchEvent(event);  return true;  }  private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {  @Override  public boolean onScale(ScaleGestureDetector detector) {   mScaleFactor *= detector.getScaleFactor(); // scale change since previous event   // Don't let the object get too small or too large.   mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));   changeMatrix();   return true;  }  }  private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {  @Override  public boolean onRotate(RotateGestureDetector detector) {   mRotationDegrees -= detector.getRotationDegreesDelta();   changeMatrix();   return true;  }  }  private class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {  @Override  public boolean onMove(MoveGestureDetector detector) {   PointF d = detector.getFocusDelta();   mFocusX += d.x;   mFocusY += d.y;   changeMatrix();   return true;  }  }  private void changeMatrix(){  float scaledImageCenterX = (getDrawable().getIntrinsicWidth()*mScaleFactor)/2;  float scaledImageCenterY = (getDrawable().getIntrinsicHeight()*mScaleFactor)/2;  mMatrix.reset();  mMatrix.postScale(mScaleFactor, mScaleFactor);  mMatrix.postRotate(mRotationDegrees, scaledImageCenterX, scaledImageCenterY);  mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY - scaledImageCenterY);  setImageMatrix(mMatrix);  } }

我们的ImageView的onTouchEvent就只剩下短短的几行代码了,然后各个detector处理完事件后,我们只需要拿到处理好的值就可以了:

 @Override  public boolean onTouchEvent(MotionEvent event) {  //把缩放事件给mScaleDetector  mScaleDetector.onTouchEvent(event);  //把旋转事件个mRotateDetector  mRotateDetector.onTouchEvent(event);  //把移动事件给mMoveDetector  mMoveDetector.onTouchEvent(event);  return true;  }

上述就是小编为大家分享的如何在Android项目中使用ImageView了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

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

AI