Android实现imageView在屏幕中缩放
16lz
2021-01-25
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); } } } }}
更多相关文章
- Android(安卓)N 程序适配要点
- 安卓屏幕完美适配方案
- Unity和Android相互通信
- App自适应draw9patch不失真背景
- Android(安卓)5.0特性
- Android图片压缩的实例详解
- Android内存优化之图片优化
- 【Android】三星Galaxy S8及S8+的屏幕适配
- 今日头条Android屏幕适配方式