IT虾米网

图片缩放,拖拽等操作详解

developer 2018年07月09日 手机开发 126 0

之前做项目要对图片的查看,然后就自己写了一个,适合对图片的浏览,跟系统图库的效果一样哦,先贴一张美女图片,听说有美女,男人就会多看一眼,不知道是不是真的,哈哈

布局文件需要注意的一点是 scaleType一定要是 matrix,这样才能对图片进行一系列的矩阵操作,例如放大缩小,拖拽,等等

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent" >  
  5.   
  6.     <ImageView  
  7.         android:id="@+id/imageView1"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent"  
  10.         android:scaleType="matrix" />  
  11.   
  12. </RelativeLayout>  

代码我都有注释,直接上代码咯
  1. package com.example.zoomanddrafting;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.graphics.Bitmap;  
  7. import android.graphics.BitmapFactory;  
  8. import android.graphics.Matrix;  
  9. import android.graphics.PointF;  
  10. import android.graphics.RectF;  
  11. import android.os.Bundle;  
  12. import android.util.DisplayMetrics;  
  13. import android.util.FloatMath;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16. import android.view.View.OnTouchListener;  
  17. import android.widget.ImageView;  
  18.   
  19.   
  20.   
  21. public class PhotoViewer extends Activity implements OnTouchListener {  
  22.   
  23.     private static final String TAG = "PhotoViewer";  
  24.     public static final int RESULT_CODE_NOFOUND = 200;  
  25.       
  26.       
  27.     Matrix matrix = new Matrix();  
  28.     Matrix savedMatrix = new Matrix();  
  29.     DisplayMetrics dm;  
  30.     ImageView imgView;  
  31.     Bitmap bitmap;  
  32.   
  33.     /** 最小缩放比例*/  
  34.     float minScaleR = 1.0f;  
  35.     /** 最大缩放比例*/  
  36.     static final float MAX_SCALE = 10f;  
  37.   
  38.     /** 初始状态*/  
  39.     static final int NONE = 0;  
  40.     /** 拖动*/  
  41.     static final int DRAG = 1;  
  42.     /** 缩放*/  
  43.     static final int ZOOM = 2;  
  44.       
  45.     /** 当前模式*/  
  46.     int mode = NONE;  
  47.   
  48.     PointF prev = new PointF();  
  49.     PointF mid = new PointF();  
  50.     float dist = 1f;  
  51.   
  52.       
  53.     @Override  
  54.     public void onCreate(Bundle savedInstanceState) {  
  55.         super.onCreate(savedInstanceState);  
  56.         // 获取图片资源  
  57.         bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.item);  
  58.           
  59.         setContentView(R.layout.activity_main);  
  60.         imgView = (ImageView) findViewById(R.id.imageView1);// 获取控件  
  61.         imgView.setImageBitmap(bitmap);// 填充控件  
  62.         imgView.setOnTouchListener(this);// 设置触屏监听  
  63.         dm = new DisplayMetrics();  
  64.         getWindowManager().getDefaultDisplay().getMetrics(dm);// 获取分辨率  
  65. //        minZoom();  
  66.         center();  
  67.         imgView.setImageMatrix(matrix);  
  68.           
  69.     }  
  70.   
  71.     public void SureOnClick(View v)  
  72.     {  
  73.           
  74.     }  
  75.       
  76.     /** 
  77.      * 触屏监听 
  78.      */  
  79.     public boolean onTouch(View v, MotionEvent event) {  
  80.   
  81.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  
  82.         // 主点按下  
  83.         case MotionEvent.ACTION_DOWN:  
  84.             savedMatrix.set(matrix);  
  85.             prev.set(event.getX(), event.getY());  
  86.             mode = DRAG;  
  87.             break;  
  88.         // 副点按下  
  89.         case MotionEvent.ACTION_POINTER_DOWN:  
  90.             dist = spacing(event);  
  91.             // 如果连续两点距离大于10,则判定为多点模式  
  92.             if (spacing(event) > 10f) {  
  93.                 savedMatrix.set(matrix);  
  94.                 midPoint(mid, event);  
  95.                 mode = ZOOM;  
  96.             }  
  97.             break;  
  98.         case MotionEvent.ACTION_UP:  
  99.         case MotionEvent.ACTION_POINTER_UP:  
  100.             mode = NONE;  
  101.             //savedMatrix.set(matrix);  
  102.             break;  
  103.         case MotionEvent.ACTION_MOVE:  
  104.             if (mode == DRAG) {  
  105.                 matrix.set(savedMatrix);  
  106.                 matrix.postTranslate(event.getX() - prev.x, event.getY()  
  107.                         - prev.y);  
  108.             } else if (mode == ZOOM) {  
  109.                 float newDist = spacing(event);  
  110.                 if (newDist > 10f) {  
  111.                     matrix.set(savedMatrix);  
  112.                     float tScale = newDist / dist;  
  113.                     matrix.postScale(tScale, tScale, mid.x, mid.y);  
  114.                 }  
  115.             }  
  116.             break;  
  117.         }  
  118.         imgView.setImageMatrix(matrix);  
  119.         CheckView();  
  120.         return true;  
  121.     }  
  122.   
  123.     /** 
  124.      * 限制最大最小缩放比例,自动居中 
  125.      */  
  126.     private void CheckView() {  
  127.         float p[] = new float[9];  
  128.         matrix.getValues(p);  
  129.         if (mode == ZOOM) {  
  130.             if (p[0] < minScaleR) {  
  131.                 //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR);  
  132.                 matrix.setScale(minScaleR, minScaleR);  
  133.             }  
  134.             if (p[0] > MAX_SCALE) {  
  135.                 //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE);  
  136.                 matrix.set(savedMatrix);  
  137.             }  
  138.         }  
  139.         center();  
  140.     }  
  141.   
  142.     /** 
  143.      * 最小缩放比例,最大为100% 
  144.      */  
  145.     private void minZoom() {  
  146.         minScaleR = Math.min(  
  147.                 (float) dm.widthPixels / (float) bitmap.getWidth(),  
  148.                 (float) dm.heightPixels / (float) bitmap.getHeight());  
  149.         if (minScaleR < 1.0) {  
  150.             matrix.postScale(minScaleR, minScaleR);  
  151.         }  
  152.     }  
  153.   
  154.     private void center() {  
  155.         center(truetrue);  
  156.     }  
  157.   
  158.     /** 
  159.      * 横向、纵向居中 
  160.      */  
  161.     protected void center(boolean horizontal, boolean vertical) {  
  162.   
  163.         Matrix m = new Matrix();  
  164.         m.set(matrix);  
  165.         RectF rect = new RectF(00, bitmap.getWidth(), bitmap.getHeight());  
  166.         m.mapRect(rect);  
  167.   
  168.         float height = rect.height();  
  169.         float width = rect.width();  
  170.   
  171.         float deltaX = 0, deltaY = 0;  
  172.   
  173.         if (vertical) {  
  174.             // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移  
  175.             int screenHeight = dm.heightPixels;  
  176.             if (height < screenHeight) {  
  177.                 deltaY = (screenHeight - height) / 2 - rect.top;  
  178.             } else if (rect.top > 0) {  
  179.                 deltaY = -rect.top;  
  180.             } else if (rect.bottom < screenHeight) {  
  181.                 deltaY = imgView.getHeight() - rect.bottom;  
  182.             }  
  183.         }  
  184.   
  185.         if (horizontal) {  
  186.             int screenWidth = dm.widthPixels;  
  187.             if (width < screenWidth) {  
  188.                 deltaX = (screenWidth - width) / 2 - rect.left;  
  189.             } else if (rect.left > 0) {  
  190.                 deltaX = -rect.left;  
  191.             } else if (rect.right < screenWidth) {  
  192.                 deltaX = screenWidth - rect.right;  
  193.             }  
  194.         }  
  195.         matrix.postTranslate(deltaX, deltaY);  
  196.     }  
  197.   
  198.     /** 
  199.      * 两点的距离 
  200.      */  
  201.     private float spacing(MotionEvent event) {  
  202.         float x = event.getX(0) - event.getX(1);  
  203.         float y = event.getY(0) - event.getY(1);  
  204.         return FloatMath.sqrt(x * x + y * y);  
  205.     }  
  206.   
  207.     /** 
  208.      * 两点的中点 
  209.      */  
  210.     private void midPoint(PointF point, MotionEvent event) {  
  211.         float x = event.getX(0) + event.getX(1);  
  212.         float y = event.getY(0) + event.getY(1);  
  213.         point.set(x / 2, y / 2);  
  214.     }  
  215.       
  216.     
  217. }  

我也将工程上传了,不要积分哦,欢迎下载 代码下载
发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

listview动态获取数据详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。