1、要求


Android中实现图片的缩放,并且图片不能完全离开屏幕。(需求比较特殊)
(1)初始化自适应屏幕的宽和高;
(2)图片可以缩放,限制图片的最大和最小缩放值;
(3)图片可以移动,但不能完全移动屏幕,即在屏幕中移动;
(4)向下移动,图片距离顶部不能超过paddingScreenMin,向上移动,图片距离底部不能超过paddingScreenMin;
(5)向左移动,如果图片放大的宽度大于屏幕的宽度,图片距离右边不能超过paddingScreenMin,如果图片放大的宽度小于屏幕的宽度,图片距离右边不能超过paddingScreenMax;
(6)向右移动,如果图片放大的宽度大于屏幕的宽度,图片距离左边不能超过paddingScreenMin,如果图片放大的宽度小于屏幕的宽度,图片距离左边不能超过paddingScreenMax;

    

2 基础知识

实现缩放和移动必须要了解Matrix的属性和方法,缩放的属性是MSCALE_X、MSCALE_Y,移动的属性是MTRANS_X、MTRANS_Y,获得这些属性的方法是void getValues (float[] values),values是一个含有9个值的一维数组。

3 源代码

 

3.1 xml文件

<?xml version="1.0" encoding="utf-8"?>    

3.2 java文件

import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PointF;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;public class ImageScaleActivity extends AppCompatActivity{    private ImageView imageViewECG = null;    private Matrix matrix = null;    private Matrix saveMatrix = null;    private boolean isFirstTouch = true;    private float maxScale = 2f;    private float minScale = 0.1f;    private float imageWidth = 1.0f;    private float imageHeight = 1.0f;    private float imageWidthInit = 1.0f;    private float imageHeightInit = 1.0f;    private float paddingScreenMin = 10.0f;    private float paddingScreenMax = 10.0f;    private PointF startPoint = null;    private PointF middlePoint = null;    private float oldDistance = 1f;    private static final int NONE = 0;    private static final int DRAG = 1;    private static final int ZOOM = 2;    private int mode = NONE;    private float[] matrixValues = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_image_scale);        this.matrix = new Matrix();        this.saveMatrix = new Matrix();        this.matrixValues = new float[9];        this.startPoint = new PointF();        this.imageViewECG = this.findViewById(R.id.report);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.report);        this.imageWidth = bitmap.getWidth();        this.imageHeight = bitmap.getHeight();        this.imageViewECG.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                // Initial the image view                ImageView imageView = (ImageView)v;                imageView.setScaleType(ImageView.ScaleType.MATRIX);                // Initial the matrix                matrix.set(imageView.getImageMatrix());                // Initial the                if(isFirstTouch){                    isFirstTouch = false;                    // Get the values of matrix                    matrix.getValues(matrixValues);                    // Initial the width of screen, scaleX = matrixValues[0], scaleY = matrixValues[4]                    minScale = matrixValues[0];                    // Initial the width and height                    imageWidthInit = imageWidth*minScale;                    imageHeightInit = imageHeight*minScale;                    paddingScreenMax = matrixValues[2];                }                // Set the gestures                switch (event.getAction() & MotionEvent.ACTION_MASK){                    // Single finger                    case MotionEvent.ACTION_DOWN:                        matrix.set(imageView.getImageMatrix());                        saveMatrix.set(matrix);                        startPoint.set(event.getX(), event.getY());                        mode = DRAG;                        break;                    // Double fingers                    case MotionEvent.ACTION_POINTER_DOWN:                        oldDistance = distanceDoubleFinger(event);                        if(distanceDoubleFinger(event)>10f){                            middlePoint = middlePoint(event);                            saveMatrix.set(matrix);                            mode = ZOOM;                        }                        break;                    // Finger slide                    case MotionEvent.ACTION_MOVE:                        if (mode == DRAG) {                            // One finger slide                            slideImage(event.getX() - startPoint.x, event.getY() - startPoint.y);                        } else if (mode == ZOOM) {                            // The double finger slide                            float newDistance = distanceDoubleFinger(event);                            // Get the values of matrix                            matrix.getValues(matrixValues);                            float newScale = newDistance/oldDistance;                            float realNewScale = matrixValues[0] * newScale;                            // Limit zooming                            if (newDistance > 10f && (realNewScale>=minScale && realNewScale<=maxScale) ) {                                matrix.set(saveMatrix);                                matrix.postScale(newScale, newScale, middlePoint.x, middlePoint.y);                            }                        }                        break;                    // Reset the double finger                    case MotionEvent.ACTION_UP:                    case MotionEvent.ACTION_POINTER_UP:                        mode = NONE;                        break;                }                // Reset the image view                imageView.setImageMatrix(matrix);                return true;            }        });    }    /**     * @param event The touch of event     * @return The distance of two point     */    private float distanceDoubleFinger(MotionEvent event) {        float x = event.getX(0) - event.getX(1);        float y = event.getY(0) - event.getY(1);        return Float.valueOf(String.valueOf(Math.sqrt(x * x + y * y))) ;    }    /*     * @param event The touch of event     * @return The PointF of middle     */    private PointF middlePoint(MotionEvent event) {        float x = event.getX(0) + event.getX(1);        float y = event.getY(0) + event.getY(1);        return new PointF(x / 2, y / 2);    }    /**     *  Slide the image     * @param distanceX Horizontal sliding distance     * @param distanceY Vertical sliding distance     */    private void slideImage(float distanceX, float distanceY){        // Get the values        float[] slideMatrixValue = new float[9];        this.matrix.getValues(slideMatrixValue);        float slideMatrixDX = slideMatrixValue[2];        float slideMatrixDY = slideMatrixValue[5];        float realWidth = this.imageWidth * slideMatrixValue[0];        float realHeight = this.imageHeight * slideMatrixValue[0];        // There are four cases for image sliding        if(distanceY >= 0){// Slide bottom            if(slideMatrixDY+distanceY < this.paddingScreenMin){                slideLeftRight(distanceX, distanceY, realWidth, slideMatrixDX);            }        }else { // distanceY < 0, Slide top            if(-(realHeight-this.imageHeightInit+slideMatrixDY+distanceY) < this.paddingScreenMin){                slideLeftRight(distanceX, distanceY, realWidth, slideMatrixDX);            }        }    }    /**     * Slide the image left and right     * @param distanceX Horizontal slide distance     * @param distanceY Vertical slide distance     * @param realWidth The width of zoomed image     * @param slideMatrixDX The horizontal slide distance recorded in matrix     */    private void slideLeftRight(float distanceX, float distanceY, float realWidth, float slideMatrixDX){        // Get the width of screen        float screenWidth = this.imageWidthInit+2*paddingScreenMax;        if (distanceX >= 0) {// distanceX >= 0            // Swipe to the right            if(realWidth > screenWidth){                // The size of the enlarged picture is larger than that of the screen.                if((slideMatrixDX+distanceX) < this.paddingScreenMin) {                    this.matrix.set(this.saveMatrix);                    this.matrix.postTranslate(distanceX, distanceY);                }            }else {                if((slideMatrixDX+distanceX) < this.paddingScreenMax) {                    this.matrix.set(this.saveMatrix);                    this.matrix.postTranslate(distanceX, distanceY);                }            }        } else {// distanceX < 0            // Swipe to the left            if(realWidth > screenWidth){                // The size of the enlarged picture is larger than that of the screen.                if((screenWidth-realWidth-slideMatrixDX-distanceX) < this.paddingScreenMin) {                    this.matrix.set(this.saveMatrix);                    this.matrix.postTranslate(distanceX, distanceY);                }            }else {                if((screenWidth-realWidth-slideMatrixDX-distanceX) < this.paddingScreenMax) {                    this.matrix.set(this.saveMatrix);                    this.matrix.postTranslate(distanceX, distanceY);                }            }        }    }}

更多相关文章

  1. Android(安卓)N 程序适配要点
  2. 安卓屏幕完美适配方案
  3. Unity和Android相互通信
  4. App自适应draw9patch不失真背景
  5. Android(安卓)5.0特性
  6. Android图片压缩的实例详解
  7. Android内存优化之图片优化
  8. 【Android】三星Galaxy S8及S8+的屏幕适配
  9. 今日头条Android屏幕适配方式

随机推荐

  1. Android(安卓)从缓存中读取图片并异步加
  2. Android利用Fiddler进行网络数据抓包
  3. Android存储访问及目录
  4. android 从驱动到应用(一)
  5. View Android Source Code in Eclipse
  6. Activity启动模式设置(堆栈中的生存时间)
  7. Android学习目录
  8. Android 学习成品
  9. android点击文本框之外的地方隐藏键盘
  10. Android设置振铃