可缩放性ImageView(可以放大缩小) |
您所在的位置:网站首页 › 缩小放大图片的软件叫什么 › 可缩放性ImageView(可以放大缩小) |
由于项目需求的原因,最近一直在研究可缩放性ImageView,用本文来记录一下最近所学: 该ImageView的实现功能有: 1)初步打开时,图片按比例满屏(填充ImageView)显示。 2)在放大缩小过程中,可以控制最大放大比例和最小缩小比例。 3)在缩放过程中,若图片的宽或高小于ImageView,则在图片在宽或高居中显示。 4)在放大后,可以移动图片,并且限制好移动的边界,不会超出图片。 5)实现双击放大或缩小的功能。(若当前图片显示为最大的比例则缩小为最小比例,若不是最小比例则放大了最大比例) 在讲代码之前,首先应该说说一个类,Matrix。因为我们在处理图片的过程中,需要图片的位移,缩放等等,而Matrix刚好就是帮我们封装好了这些数据,具体的,大家可以看看这篇文章:android 从matrix获取处理过的图片的实际宽度重点是了解Matrix里面数组的含义。 上代码,具体的说明代码都有一一介绍: MyZoomImageView.java文件: [java] view plain copy package com.xiaoyan.doubletouch; import android.content.Context; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ImageView; /** * 缩放ImageView * * @author xiejinxiong * */ public class MyZoomImageView extends ImageView { /** ImageView高度 */ private int imgHeight; /** ImageView宽度 */ private int imgWidth; /** 图片高度 */ private int intrinsicHeight; /** 图片宽度 */ private int intrinsicWidth; /** 最大缩放级别 */ private float mMaxScale = 2.0f; /** 最小缩放级别 */ private float mMinScale = 0.2f; /** 用于记录拖拉图片移动的坐标位置 */ private Matrix matrix = new Matrix(); /** 用于记录图片要进行拖拉时候的坐标位置 */ private Matrix currentMatrix = new Matrix(); /** 记录第一次点击的时间 */ private long firstTouchTime = 0; /** 时间点击的间隔 */ private int intervalTime = 250; /** 第一次点完坐标 */ private PointF firstPointF; public MyZoomImageView(Context context) { super(context); initUI(); } public MyZoomImageView(Context context, AttributeSet attrs) { super(context, attrs); initUI(); } public MyZoomImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub initUI(); } /** * 初始化UI */ private void initUI() { this.setScaleType(ScaleType.FIT_CENTER); this.setOnTouchListener(new TouchListener()); getImageViewWidthHeight(); getIntrinsicWidthHeight(); } /** * 获得图片内在宽高 */ private void getIntrinsicWidthHeight() { Drawable drawable = this.getDrawable(); // 初始化bitmap的宽高 intrinsicHeight = drawable.getIntrinsicHeight(); intrinsicWidth = drawable.getIntrinsicWidth(); } private final class TouchListener implements OnTouchListener { /** 记录是拖拉照片模式还是放大缩小照片模式 */ private int mode = 0;// 初始状态 /** 拖拉照片模式 */ private static final int MODE_DRAG = 1; /** 放大缩小照片模式 */ private static final int MODE_ZOOM = 2; /** 用于记录开始时候的坐标位置 */ private PointF startPoint = new PointF(); /** 两个手指的开始距离 */ private float startDis; /** 两个手指的中间点 */ private PointF midPoint; public boolean onTouch(View v, MotionEvent event) { /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */ switch (event.getAction() & MotionEvent.ACTION_MASK) {// 单点监听和多点触碰监听 // 手指压下屏幕 case MotionEvent.ACTION_DOWN: mode = MODE_DRAG; // 记录ImageView当前的移动位置 currentMatrix.set(getImageMatrix()); startPoint.set(event.getX(), event.getY()); matrix.set(currentMatrix); makeImageViewFit(); break; // 手指在屏幕上移动,改事件会被不断触发 case MotionEvent.ACTION_MOVE: // 拖拉图片 if (mode == MODE_DRAG) { // System.out.println("ACTION_MOVE_____MODE_DRAG"); float dx = event.getX() - startPoint.x; // 得到x轴的移动距离 float dy = event.getY() - startPoint.y; // 得到x轴的移动距离 // 在没有移动之前的位置上进行移动z matrix.set(currentMatrix); float[] values = new float[9]; matrix.getValues(values); dx = checkDxBound(values, dx); dy = checkDyBound(values, dy); matrix.postTranslate(dx, dy); } // 放大缩小图片 else if (mode == MODE_ZOOM) { float endDis = distance(event);// 结束距离 if (endDis > 10f) { // 两个手指并拢在一起的时候像素大于10 float scale = endDis / startDis;// 得到缩放倍数 matrix.set(currentMatrix); float[] values = new float[9]; matrix.getValues(values); scale = checkFitScale(scale, values); matrix.postScale(scale, scale, midPoint.x, midPoint.y); } } break; // 手指离开屏幕 case MotionEvent.ACTION_UP: setDoubleTouchEvent(event); case MotionEvent.ACTION_POINTER_UP: // System.out.println("ACTION_POINTER_UP"); mode = 0; // matrix.set(currentMatrix); float[] values = new float[9]; matrix.getValues(values); makeImgCenter(values); break; // 当屏幕上已经有触点(手指),再有一个触点压下屏幕 case MotionEvent.ACTION_POINTER_DOWN: // System.out.println("ACTION_POINTER_DOWN"); mode = MODE_ZOOM; /** 计算两个手指间的距离 */ startDis = distance(event); /** 计算两个手指间的中间点 */ if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10 midPoint = mid(event); // 记录当前ImageView的缩放倍数 currentMatrix.set(getImageMatrix()); } break; } setImageMatrix(matrix); return true; } /** 计算两个手指间的距离 */ private float distance(MotionEvent event) { float dx = event.getX(1) - event.getX(0); float dy = event.getY(1) - event.getY(0); /** 使用勾股定理返回两点之间的距离 */ return FloatMath.sqrt(dx * dx + dy * dy); } /** 计算两个手指间的中间点 */ private PointF mid(MotionEvent event) { float midX = (event.getX(1) + event.getX(0)) / 2; float midY = (event.getY(1) + event.getY(0)) / 2; return new PointF(midX, midY); } /** * 和当前矩阵对比,检验dy,使图像移动后不会超出ImageView边界 * * @param values * @param dy * @return */ private float checkDyBound(float[] values, float dy) { float height = imgHeight; if (intrinsicHeight * values[Matrix.MSCALE_Y] 0) dy = -values[Matrix.MTRANS_Y]; else if (values[Matrix.MTRANS_Y] + dy |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |