`
119568242
  • 浏览: 426953 次
  • 性别: Icon_minigender_1
  • 来自: 深圳/湛江
社区版块
存档分类
最新评论

[android]使用 Matrix 的随触摸旋转的ImageView

 
阅读更多

使用 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);
		}

	}

}

 

分享到:
评论

相关推荐

    Android开发之ImageView通过matrix实现两点缩放和图片拖动

    Matrix是Android图形系统中的一个关键类,它允许我们对坐标系统进行变换,包括平移、旋转、缩放等。 首先,我们需要理解Matrix的工作原理。Matrix是一个3x3的矩阵,它可以表示2D图形的各种变换。在Android中,我们...

    android 利用matrix实现图片的旋转与缩放

    当用户触摸屏幕并拖动时,可以计算出触摸点相对于图片中心的偏移量,然后使用Matrix进行相应的旋转和缩放。 例如,我们可以在`MatrixTest`这个项目中创建一个Activity,然后在布局文件中添加一个ImageView,设置其...

    Android Matrix处理ImageView中图片缩放,平移

    Matrix类是Android提供的一种强大的工具,它允许我们对图像进行复杂的几何变换,如旋转、缩放、平移和倾斜。本文将深入探讨如何利用Matrix处理ImageView中的图片缩放和平移操作。 首先,我们需要了解Matrix的基本...

    android自定义控件继承imageview,实现拖拽,缩放,旋转

    在实际编码中,可能还需要考虑到性能优化,例如使用GestureDetector和ScaleGestureDetector来处理特定的触摸手势,或者使用Matrix来更高效地进行图像变换。 通过以上步骤,我们可以创建一个功能强大的自定义...

    AndroidImageView控件缩放和旋转图片源码.zip

    在Android SDK中,ImageView提供了Matrix类来处理图像的变换,包括缩放、平移和旋转。缩放图片通常通过设置ImageView的scaleType属性来实现,它有多种模式,如center、centerCrop、fitCenter、fitStart、fitEnd、...

    Android使用Matrix实现图片缩放,移动

    本文将深入探讨如何使用Android的Matrix类来实现这一功能,同时避免内存溢出(OOM)问题。 Matrix是Android图形库中的核心类,用于表示2D变换矩阵,它可以执行平移(translation)、旋转(rotation)、缩放...

    Android 多点触摸(Multitouch ImageView)

    综上所述,实现一个支持多点触摸的Multitouch ImageView需要理解Android的触摸事件处理机制,掌握Matrix和Animator的使用,以及如何处理拖拽、缩放和旋转等操作。通过对这些知识点的深入理解和实践,开发者可以创建...

    Android 自定义ImageView(移动、缩放、旋转)

    在`onDraw()`方法中,使用`canvas.drawBitmap()`结合`Matrix`进行绘制,这样就可以看到图像根据手势进行了相应的移动、缩放和旋转。 总结一下,创建一个自定义的`MutiTouchImageView`涉及到以下几个关键步骤: 1. ...

    android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果

    这个自定义ImageView的实现,通常会涉及到Android的触摸事件处理、Matrix变换以及手势识别等技术。 首先,我们要了解Android中的手势识别。Android提供了GestureDetector和ScaleGestureDetector这两个类来帮助我们...

    matrix键盘缩放旋转图片

    总结来说,这个项目通过使用Android的Matrix类和ImageView组件,实现了键盘控制下的图片缩放和旋转功能。在实际应用中,可以根据需求添加更多交互逻辑,如手势识别、滑动动画等,以提升用户体验。同时,理解并熟练...

    Android应用源码之imageView1_imageView.zip

    这个名为"Android应用源码之imageView1_imageView.zip"的压缩包很可能包含了一个简单的Android应用示例,该示例专门针对ImageView的使用进行演示。在这里,我们将深入探讨ImageView在Android开发中的使用和相关知识...

    android手机应用源码ImageView控件缩放和旋转图片源码.rar

    - setRotation度数:从API 30(Android R)开始,ImageView提供了setRotation()方法,可以直接设置图像的旋转角度,这比使用Matrix更加方便。 在实际应用中,我们可能需要处理用户手势来动态缩放和旋转图片。例如...

    左右翻转的ImageView

    在Android中,这种效果可以通过矩阵操作来实现,通过修改ImageView的Matrix属性,我们可以控制图片的旋转角度。 "ImageRotate"框架正是为了解决这个问题而设计的,它提供了一个定制化的ImageView类,该类扩展了...

    android imageview 图片缩放

    在ImageView的onTouchEvent()事件中,我们可以获取到触摸事件的坐标,根据这些坐标更新Matrix,然后通过setImageMatrix()方法将新的Matrix应用到ImageView上。这样,用户就可以通过手指滑动来实现图片的平移,双指...

    android 自定义imageview(手势放大,缩小,旋转)

    本文将深入探讨如何基于Android的ImageView组件创建一个自定义视图,实现手势操作,包括图像的放大、缩小和旋转功能。 首先,我们需要了解Android的手势检测机制。Android提供了GestureDetector和...

    Android ImageView控件缩放和旋转图片源码-IT计算机-毕业设计.zip

    - 在Android中,可以使用`ScaleType`属性来控制ImageView内的图片缩放方式。常见的缩放类型有:`CENTER`, `CENTER_CROP`, `CENTER_INSIDE`, `FIT_CENTER`, `FIT_START`, `FIT_END`, `FIT_XY`等。 - `FitXY`会按...

    Android ImageView控件缩放和旋转图片源码.rar

    这个压缩包"Android ImageView控件缩放和旋转图片源码.rar"显然包含了实现ImageView图像缩放和旋转功能的源代码。以下是对这些关键知识点的详细解释: 1. **ImageView**: - ImageView是Android SDK中的一个视图类...

    Android ImageView控件缩放和旋转图片源码.zip

    - 除了手动更新Matrix,还可以使用Android的动画系统,如`ViewPropertyAnimator`或`ObjectAnimator`,为图片的缩放和旋转添加平滑的动画效果。 9. **Android布局**: - 考虑到ImageView在布局中的位置和大小,...

    android 可放大缩小拖动的ImageView

    `Matrix`是Android中用于表示二维图形变换的类,可以用来表示平移、旋转、缩放等操作。在代码中,`mMatrix`变量被用来保存图片当前的变换状态。 #### 2.2 图片尺寸获取 当设置新的图片时,会调用`setImageBitmap`...

    ImageView的放缩和旋转

    1. Matrix旋转:同样使用Matrix对象,调用`postRotate()`方法设置旋转角度,然后应用到ImageView。 2. 动画旋转:可以使用`android.view.animation`包中的`RotateAnimation`类创建旋转动画,设置起始角度、结束角度...

Global site tag (gtag.js) - Google Analytics