自定义ImageView实现图片的单指拖动和两指缩放
来源:互联网 发布:荷塘月色淘宝 编辑:程序博客网 时间:2024/06/12 01:22
MainActivity如下:
package cn.testtouchscreentomoveimage;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;/** * Demo描述: * 通过自定义ImageView实现ImageView中图片的单指拖动和两指缩放 * * 参考资料: * 1 http://blog.csdn.net/lfdfhl/article/details/8248848 * 2 http://blog.csdn.net/leverage_1229/article/details/9009931 * Thank you very much * */public class MainActivity extends Activity {private Bitmap mBitmap; private ZoomImageView mZoomImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); }private void init() {mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.e);mZoomImageView = (ZoomImageView) findViewById(R.id.imageView);mZoomImageView.setBitmap(mBitmap);}@Overrideprotected void onDestroy() {super.onDestroy();if (mBitmap!=null) {mBitmap.recycle();}}}
ZoomImageView如下:
package cn.testtouchscreentomoveimage;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.PointF;import android.util.AttributeSet;import android.util.FloatMath;import android.view.MotionEvent;import android.widget.ImageView;/** * PS: * 整理时间2014年8月14日22:40:34 * * 核心方法: * canvas.drawBitmap(bitmap, matrix, paint) * 重点在于去操作一个Matrix. * 该处主要用到的是利用Matrix实现缩放(Scale)和位移(Translate) * * * mMatrix和mCurrentMatrix的说明 * 这是以前写的Demo了,今天在重新整理看到这两个Matrix居然一下子 * 没有反应过来.所以在此写下笔记,记录下来. * 在这个示例中一共涉及到两个Matrix,它们分别有什么用呢? * mMatrix.postScale()和mMatrix.postTranslate()起到实际作用的 * 是mMatrix.但是请注意,这些postScale和postTranslate是基于以往 * 的matrix的,就是说现在这个mMatrix执行的操作是在原来的矩阵matrix * 的基础上进行的. * 比如第一次是scale缩放操作,得到的矩阵是matrix1,这个时候停止操作 * 图片已经改变了原来的样子 * 然后接着进行第二次的操作,再进行translate位移操作,它就是在第一次 * 的结果上继续上操作的;从代码上来看,现在的matrix要在上一次的matrix * 进行操作. * 所以我们需要一个变量来记录上次操作后的矩阵,即此处的mCurrentMatrix * * * * 关于CURRENT_MODE == ZOOM_MODE时的说明: * 每次的缩放scale都是相对于两指头放在屏幕上的最初状态而言的. * 什么意思呢?解释如下: * if (CURRENT_MODE == ZOOM_MODE) { * 在这段代码中twoFingers_distance_before_move是不变的. * 但是twoFingers_distance_after_move在两指操作缩放的过程 * 中是持续变大或者变小的. * 这样导致了计算出来的scale是持续变大或者边小的. * 比如在两指慢慢放大的过程中,从输出的Log可以发现这个scale在 * 一直变大,哪怕是放大的动作很小此时的scale也是1.X,但是图片也只 * 变大了一点点没有突然变很大.因为每次的缩放都是针对缩放前的状态 * 而言的,而不是针对上一次缩放而言.举例吧: * status1:两指放在屏幕上的状态 * 然后两指持续在屏幕上慢慢的MOVE实现放大,每一次微小的放大都构成 * 了一次新的状态 * status2:放大了一点 * status3:持续放大了一点 * status4:又持续放大了一点 * status5:再一次持续放大了一点 * ......................... * status5,status4的放大都是针对status1而言的,而不是针对它们的上一次 * status4或者status3而言. * 所以每次都要先复制原来的matrix再进行缩放,代码如下: * * mMatrix.set(mCurrentMatrix); * //依据缩放比例和中心点进行缩放 * mMatrix.postScale(scale, scale, mMiddlePointF.x,mMiddlePointF.y); * } * * * * 注意事项: * 在该Demo中对于ImageView的设置 * android:layout_width="match_parent" * android:layout_height="match_parent" * 是不太合理的,在具体项目中应调整 * */public class ZoomImageView extends ImageView {// 图片private Bitmap mBitmap;// 开始点private PointF mStartPoinF;// 图片位置的变换矩阵private Matrix mMatrix;// 图片当前矩阵private Matrix mCurrentMatrix;// 模式参数private int CURRENT_MODE = 0;// 初始模式 private static final int INIT_MODE = 1;// 拖拉模式private static final int DRAG_MODE = 2;// 缩放模式private static final int ZOOM_MODE = 3;// 开启缩放的阈值private static final float ZOOM_THRESHOLD = 10.0f;// 缩放前两指间的距离private float twoFingers_distance_before_move;// 缩放后两指间的距离private float twoFingers_distance_after_move;// 两指间中心点private PointF mMiddlePointF; public ZoomImageView(Context context) {super(context);}public ZoomImageView(Context context, AttributeSet attrs) {super(context, attrs);}public ZoomImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public void setBitmap(Bitmap bitmap){CURRENT_MODE=INIT_MODE;mBitmap=bitmap;mStartPoinF = new PointF();mMatrix = new Matrix();mCurrentMatrix = new Matrix();invalidate();}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:CURRENT_MODE = DRAG_MODE;// 记录图片当前matrixmCurrentMatrix.set(mMatrix);// 记录开始坐标pointmStartPoinF.set(event.getX(), event.getY());break;// 当屏幕上已经有触点(手指),再有手指按下时触发该事件case MotionEvent.ACTION_POINTER_DOWN:CURRENT_MODE = ZOOM_MODE;twoFingers_distance_before_move = getTwoPointsDistance(event);if (twoFingers_distance_before_move > ZOOM_THRESHOLD) {// 计算两触点的中心点mMiddlePointF = getMiddlePoint(event);}break;case MotionEvent.ACTION_MOVE://拖动模式下--->处理图片的拖动if (CURRENT_MODE == DRAG_MODE) {// 获取X轴移动距离float distanceX = event.getX() - mStartPoinF.x;// 获取Y轴移动距离float distanceY = event.getY() - mStartPoinF.y;// 在mCurrentMatrix的基础上平移图片,所以将mCurrentMatrix复制到mMatrixmMatrix.set(mCurrentMatrix);mMatrix.postTranslate(distanceX, distanceY);} //缩放模式下--->处理图片的缩放if (CURRENT_MODE == ZOOM_MODE) {twoFingers_distance_after_move = getTwoPointsDistance(event);if (twoFingers_distance_after_move > ZOOM_THRESHOLD) {// 计算缩放比例float scale = twoFingers_distance_after_move / twoFingers_distance_before_move;// 在mCurrentMatrix的基础上缩放图片,所以将mCurrentMatrix复制到mMatrix mMatrix.set(mCurrentMatrix);// 依据缩放比例和中心点进行缩放mMatrix.postScale(scale, scale, mMiddlePointF.x,mMiddlePointF.y);}}break;case MotionEvent.ACTION_UP:// 当手指离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件case MotionEvent.ACTION_POINTER_UP:CURRENT_MODE = 0;break;}invalidate();return true;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawBitmap(mBitmap, mMatrix, null);} //计算两点之间的距离 public static float getTwoPointsDistance(MotionEvent event) { float disX = event.getX(1) - event.getX(0); float disY = event.getY(1) - event.getY(0); return FloatMath.sqrt(disX * disX + disY * disY); } //计算两点之间的中间点 public static PointF getMiddlePoint(MotionEvent event) { float midX = (event.getX(0) + event.getX(1)) /2; float midY = (event.getY(0) + event.getY(1)) /2; return new PointF(midX, midY); }}
main.xml如下:
<?xml version="1.0" encoding="utf-8" ?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <cn.testtouchscreentomoveimage.ZoomImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="matrix" /></LinearLayout>
- 自定义ImageView实现图片的单指拖动和两指缩放
- 自定义ImageView实现图片的拖动、缩放和边界回弹
- 自定义类继承ImageView 实现多点图片触碰的拖动和缩放
- 自定义类继承ImageView 实现多点图片触碰的拖动和缩放
- 缩放图片的ImageView 可以进行两指缩放,并且可以进行拖拉的ImageView最简单原生的实现
- 自定义View实现图片的拖动和缩放
- 自定义View实现图片的拖动和缩放
- 自定义的ImageView控制,可对图片进行多点触控缩放和拖动
- 自定义ImageView实现拖动,缩放,旋转功能
- 自定义ImageView实现拖动、旋转、缩放功能
- 单指拖动、双指缩放图片
- ViewPager中实现对图片的单指拖动缩放旋转
- Android-实现图片的拖动和缩放
- Android实现图片的缩放和拖动
- Android自定义imageview可对图片进行多点缩放和拖动
- Android开发之ImageView通过matrix实现两点缩放和图片拖动
- Android手势:单指拖动、双指缩放图片
- Android手势:单指拖动、双指缩放图片
- 老师们都是这样计算毕业设计分数的
- MySQL Binlog (异常) unknown variable 'default-character-set=utf8'
- 关于C语言和汇编语言相互嵌套调用
- MYSQL 主从热备方式配置
- Eclipse快捷键 10个最有用的快捷键
- 自定义ImageView实现图片的单指拖动和两指缩放
- jquery 事件 trigger
- EditText 区别输入中文还是英文
- 黑马程序员——java面试题之交通等管理系统
- Vtiger Dashboard翻译问题
- 心情特烦
- Qt C++ bridge模式(桥)
- jquery 轮询图片
- 第十三堂作业