Android之Matrix学习(一)
2016-06-13 14:07
525 查看
使用Matrix实现图片移动和多点触摸
一、什么是Matrix?其实在Android中Matrix本质是一个3*3的矩阵Matrix包括的图形处理包括以下4种。
-Translate 平移变换
-scale 缩放变换
-rotate 旋转变换
-skew 错切变换
前面三个比较容易理解,有点类似于动画中的变化,就不做介绍了,最后一个错切变化在数学上又称为Shear mapping或者Transvection,它是一种比较特殊的线性变换。错切变换的效果就是让所有点的X坐标(或者Y坐标)保持不变,让Y(X)坐标进行按比例发生平移,而且平移的大小和该点到X(Y)周的垂直距离成正比。错切变换的公式如下:
x = x0 + K1 * y0
y=K2*x0+y0
这篇博客用的技术只用到了Matrix的平移变换,其它的在后续会讲到。
OK,上代码。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" tools:context="${relativePackage}.${activityClass}" > <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="matrix" android:src="@drawable/img" /> </RelativeLayout>
这个布局中只有一个ImageView,注意:要想让图片可以通过Matrix实现变化,必须加这行代码,否则不会起作用。
android:scaleType=”matrix”
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIv = (ImageView) findViewById(R.id.iv); mStartPoint = new PointF(); matrix = new Matrix(); mCurrentMatrix = new Matrix(); mIv.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: //将模式改为拖拽 mode = DRAG ; //当手指按下的时候,记录一开始按下的位置 mCurrentMatrix.set(mIv.getImageMatrix()); mStartPoint.x = event.getX(); mStartPoint.y = event.getY() ; break; case MotionEvent.ACTION_MOVE: if(mode == DRAG){ //计算移动的距离 float dx = event.getX() - mStartPoint.x ; float dy = event.getY() - mStartPoint.y; //在没有移动的基础上开始移动 matrix.set(mCurrentMatrix); matrix.set(mCurrentMatrix); //利用矩阵移动 matrix.postTranslate(dx, dy) ; }else if(mode == ZOOM){ mMoveInstance = distance(event); //计算缩放比例 float scale = mMoveInstance / mStartInstance ; centerP = calculateCenter(event); //基于上一次的放大倍数基础上进行缩放 matrix.set(mCurrentMatrix); System.out.println("scale:" + scale ); matrix.postScale(scale, scale, centerP.x , centerP.y ) ; } break; //在第二根手指按下的时候计算此时的距离 case MotionEvent.ACTION_POINTER_DOWN: mStartInstance = distance(event); centerP = calculateCenter(event); //记录当前的矩阵 mCurrentMatrix.set(mIv.getImageMatrix()); //将模式改为缩放 mode = ZOOM ; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = 0 ; break; } mIv.setImageMatrix(matrix); return true;//将事件消费 } }); }
可能有些童鞋不太了解event.getActionMasked(),其实,我们点进去看源码知道点了
public final int getActionMasked() {
return nativeGetAction(mNativePtr) & ACTION_MASK;
}
而getAction()的源码如下:
public final int getAction() {
return nativeGetAction(mNativePtr);
}
ACTION_MASK到底是什么呢?
/**
* Bit mask of the parts of the action code that are the action itself.
*/
public static final int ACTION_MASK = 0xff;
protected PointF calculateCenter(MotionEvent event) { float dx = event.getX(1) + event.getX(0); float dy = event.getY(1)+event.getY(0); return new PointF(dx / 2 ,dy / 2); }
protected float distance(MotionEvent event) { float x = event.getX(1) - event.getX(0); float y = event.getY(1) - event.getY(0); return (float) Math.sqrt(x * x + y * y) ; }
由此可以看出getActionMasked()就相当于getAction()&&255,相当于将高位屏蔽掉了。总之,记住,要想实现多点触摸,就使用getActionMasked()。然后就是每次按下的时候需要设置下当前图片的矩阵值,使在移动的时候在此基础上进行移动.其它的就没有太难的地方,在草稿纸上画画就应该出来了
运行结果:
源码下载
相关文章推荐
- ubuntu14.04 kylin使用android studio时,adb 报错
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
- android第一次启动时Settings的默认值
- 安卓获得系统时间
- AndroidStudio导入Git Project
- 关于event.getX()与event.getRawX()的问题
- android源码的一些文件路径
- android 隐藏系统键盘
- Android 使用WebService
- Android Notification使用方法
- 【Android】ListView ViewHolder ArrayIndexOutOfBoundsException: length=2; index=2
- android状态栏样式修改
- Android LayoutInflater详解
- Android有效地减少方法数
- Android入门-SayHello及其多种实现方法
- 菜逼的Android旅程
- AndroidStudio 错误
- Android 开发注意事项
- Android异步任务:AsyncTask 和 Handler+Message详解
- Android 自定义Dialog(自定义主题、自定义布局