使用 Matrix 的随触摸旋转的ImageView
突然想做个 类似 旋转开关的东西。然后就用了surfaceView做了个一个。
快做完的时候 朋友说道可以使用imageView来实现我想要的效果,然后就研究了下。
几个keypoint点
1.需要设置setScaleType(ScaleType.MATRIX);
2.matrix 需要new出来 通过getImageMatrix()的不行
3.通过setImageMatrix() 会调用invalidate() 从而重绘。
另外:
Matrix的
postRotate与setRotate
postRotate会基于Matrix上次的矩阵旋转
而setRotate会重置矩阵然后旋转
注:可延伸至Matrix 的postXX setXX
普通旋转:
iv 为imageView对象。
Matrix m=new Matrix();
m.postRotate(30f,iv.getWidth()/2,iv.getHeight()/2);
iv.setImageMatrix(m);
代码如下:
package com.lurencun.poolotools.ui.light; import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.ImageView; /** * 随触摸旋转ImageView * * @author liupoolo * @since 2013-02-22 * @version 1.00 */ public class TouchRoateImageView extends ImageView { private final static float MIN_DEGREE = 0f; private final static float MAX_DEGREE = 360f; private Matrix m; private float saveX; // 当前保存的x private float saveY; // 当前保存的y private float curTouchX; // 当前触屏的x private float curTouchY; // 当前触摸的y private float centerX; // 中心点x private float centerY; // 中心点y private float curDegree; // 当前角度 private float changeDegree; public TouchRoateImageView(Context context, AttributeSet attrs) { super(context, attrs); setScaleType(ScaleType.MATRIX);// 重点 m = new Matrix(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); centerX = this.getWidth() / 2; centerY = this.getHeight() / 2; } public boolean onTouchEvent(MotionEvent event) { handleTouch(event); return true; } private void handleTouch(MotionEvent event) { curTouchX = event.getX(); curTouchY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: saveTouchPoint(); break; case MotionEvent.ACTION_MOVE: handleTouchMove(); break; case MotionEvent.ACTION_UP: // 可以使用访问者模式这里让访问者获得当前角度 break; } } private void handleTouchMove() { changeDegree = (float) getActionDegrees(centerX, centerY, saveX, saveY, curTouchX, curTouchY); float tempDegree = (float) curDegree + changeDegree; if (tempDegree >= MIN_DEGREE && tempDegree <= MAX_DEGREE) { optimize(tempDegree);//优化变动 m.setRotate(curDegree, centerX, centerY); setImageMatrix(m);// 此方法会 调用invalidate() 从而重绘界面 } saveTouchPoint(); } private void optimize(float tempDegree){ if(tempDegree>MAX_DEGREE-1){ curDegree=MAX_DEGREE; }else if(tempDegree<MIN_DEGREE+1){ curDegree=MIN_DEGREE; }else{ this.curDegree = tempDegree; } } private void saveTouchPoint() { saveX = curTouchX; saveY = curTouchY; } /** * 获取两点到第三点的夹角。 * * @param x * @param y * @param x1 * @param y1 * @param x2 * @param y2 * @return */ private double getActionDegrees(float x, float y, float x1, float y1, float x2, float y2) { double a = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); double b = Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); double c = Math.sqrt((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y)); // 余弦定理 double cosA = (b * b + c * c - a * a) / (2 * b * c); // 返回余弦值为指定数字的角度,Math函数为我们提供的方法 double arcA = Math.acos(cosA); double degree = arcA * 180 / Math.PI; // 接下来我们要讨论正负值的关系了,也就是求出是顺时针还是逆时针。 // 第1、2象限 if (y1 < y && y2 < y) { if (x1 < x && x2 > x) {// 由2象限向1象限滑动 return degree; } // 由1象限向2象限滑动 else if (x1 >= x && x2 <= x) { return -degree; } } // 第3、4象限 if (y1 > y && y2 > y) { // 由3象限向4象限滑动 if (x1 < x && x2 > x) { return -degree; } // 由4象限向3象限滑动 else if (x1 > x && x2 < x) { return degree; } } // 第2、3象限 if (x1 < x && x2 < x) { // 由2象限向3象限滑动 if (y1 < y && y2 > y) { return -degree; } // 由3象限向2象限滑动 else if (y1 > y && y2 < y) { return degree; } } // 第1、4象限 if (x1 > x && x2 > x) { // 由4向1滑动 if (y1 > y && y2 < y) { return -degree; } // 由1向4滑动 else if (y1 < y && y2 > y) { return degree; } } // 在特定的象限内 float tanB = (y1 - y) / (x1 - x); float tanC = (y2 - y) / (x2 - x); if ((x1 > x && y1 > y && x2 > x && y2 > y && tanB > tanC)// 第一象限 || (x1 > x && y1 < y && x2 > x && y2 < y && tanB > tanC)// 第四象限 || (x1 < x && y1 < y && x2 < x && y2 < y && tanB > tanC)// 第三象限 || (x1 < x && y1 > y && x2 < x && y2 > y && tanB > tanC))// 第二象限 return -degree; return degree; } public float getCurDegree() { return curDegree; } public void setCurDegree(float curDegree) { if (curDegree >= MIN_DEGREE && curDegree <= MAX_DEGREE) { this.curDegree = curDegree; m.setRotate(curDegree, centerX, centerY); setImageMatrix(m); } } }
相关推荐
Matrix是Android图形系统中的一个关键类,它允许我们对坐标系统进行变换,包括平移、旋转、缩放等。 首先,我们需要理解Matrix的工作原理。Matrix是一个3x3的矩阵,它可以表示2D图形的各种变换。在Android中,我们...
当用户触摸屏幕并拖动时,可以计算出触摸点相对于图片中心的偏移量,然后使用Matrix进行相应的旋转和缩放。 例如,我们可以在`MatrixTest`这个项目中创建一个Activity,然后在布局文件中添加一个ImageView,设置其...
Matrix类是Android提供的一种强大的工具,它允许我们对图像进行复杂的几何变换,如旋转、缩放、平移和倾斜。本文将深入探讨如何利用Matrix处理ImageView中的图片缩放和平移操作。 首先,我们需要了解Matrix的基本...
在实际编码中,可能还需要考虑到性能优化,例如使用GestureDetector和ScaleGestureDetector来处理特定的触摸手势,或者使用Matrix来更高效地进行图像变换。 通过以上步骤,我们可以创建一个功能强大的自定义...
在Android SDK中,ImageView提供了Matrix类来处理图像的变换,包括缩放、平移和旋转。缩放图片通常通过设置ImageView的scaleType属性来实现,它有多种模式,如center、centerCrop、fitCenter、fitStart、fitEnd、...
本文将深入探讨如何使用Android的Matrix类来实现这一功能,同时避免内存溢出(OOM)问题。 Matrix是Android图形库中的核心类,用于表示2D变换矩阵,它可以执行平移(translation)、旋转(rotation)、缩放...
综上所述,实现一个支持多点触摸的Multitouch ImageView需要理解Android的触摸事件处理机制,掌握Matrix和Animator的使用,以及如何处理拖拽、缩放和旋转等操作。通过对这些知识点的深入理解和实践,开发者可以创建...
在`onDraw()`方法中,使用`canvas.drawBitmap()`结合`Matrix`进行绘制,这样就可以看到图像根据手势进行了相应的移动、缩放和旋转。 总结一下,创建一个自定义的`MutiTouchImageView`涉及到以下几个关键步骤: 1. ...
这个自定义ImageView的实现,通常会涉及到Android的触摸事件处理、Matrix变换以及手势识别等技术。 首先,我们要了解Android中的手势识别。Android提供了GestureDetector和ScaleGestureDetector这两个类来帮助我们...
总结来说,这个项目通过使用Android的Matrix类和ImageView组件,实现了键盘控制下的图片缩放和旋转功能。在实际应用中,可以根据需求添加更多交互逻辑,如手势识别、滑动动画等,以提升用户体验。同时,理解并熟练...
这个名为"Android应用源码之imageView1_imageView.zip"的压缩包很可能包含了一个简单的Android应用示例,该示例专门针对ImageView的使用进行演示。在这里,我们将深入探讨ImageView在Android开发中的使用和相关知识...
- setRotation度数:从API 30(Android R)开始,ImageView提供了setRotation()方法,可以直接设置图像的旋转角度,这比使用Matrix更加方便。 在实际应用中,我们可能需要处理用户手势来动态缩放和旋转图片。例如...
在Android中,这种效果可以通过矩阵操作来实现,通过修改ImageView的Matrix属性,我们可以控制图片的旋转角度。 "ImageRotate"框架正是为了解决这个问题而设计的,它提供了一个定制化的ImageView类,该类扩展了...
在ImageView的onTouchEvent()事件中,我们可以获取到触摸事件的坐标,根据这些坐标更新Matrix,然后通过setImageMatrix()方法将新的Matrix应用到ImageView上。这样,用户就可以通过手指滑动来实现图片的平移,双指...
本文将深入探讨如何基于Android的ImageView组件创建一个自定义视图,实现手势操作,包括图像的放大、缩小和旋转功能。 首先,我们需要了解Android的手势检测机制。Android提供了GestureDetector和...
- 在Android中,可以使用`ScaleType`属性来控制ImageView内的图片缩放方式。常见的缩放类型有:`CENTER`, `CENTER_CROP`, `CENTER_INSIDE`, `FIT_CENTER`, `FIT_START`, `FIT_END`, `FIT_XY`等。 - `FitXY`会按...
这个压缩包"Android ImageView控件缩放和旋转图片源码.rar"显然包含了实现ImageView图像缩放和旋转功能的源代码。以下是对这些关键知识点的详细解释: 1. **ImageView**: - ImageView是Android SDK中的一个视图类...
- 除了手动更新Matrix,还可以使用Android的动画系统,如`ViewPropertyAnimator`或`ObjectAnimator`,为图片的缩放和旋转添加平滑的动画效果。 9. **Android布局**: - 考虑到ImageView在布局中的位置和大小,...
`Matrix`是Android中用于表示二维图形变换的类,可以用来表示平移、旋转、缩放等操作。在代码中,`mMatrix`变量被用来保存图片当前的变换状态。 #### 2.2 图片尺寸获取 当设置新的图片时,会调用`setImageBitmap`...
1. Matrix旋转:同样使用Matrix对象,调用`postRotate()`方法设置旋转角度,然后应用到ImageView。 2. 动画旋转:可以使用`android.view.animation`包中的`RotateAnimation`类创建旋转动画,设置起始角度、结束角度...