zoukankan      html  css  js  c++  java
  • Android 自定义ImageView支持缩放,拖拽,方便复用

    今天刚发了一篇关于ImageView的缩放和拖拽的博客,然后我想了下,将他自定义下,方便我们来复用这个imageView,效果我就不多说了,http://blog.csdn.net/xiaanming/article/details/8827257就是这个效果,我只是把他抽出来自定义了下,代码还是贴上吧,我也将demo上传一下,有疑问大家指出来,大家共同学习,共同进步,呵呵

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. package com.example.myimageview;  
    2.   
    3. import android.content.Context;  
    4. import android.graphics.Bitmap;  
    5. import android.graphics.Matrix;  
    6. import android.graphics.PointF;  
    7. import android.graphics.RectF;  
    8. import android.graphics.drawable.BitmapDrawable;  
    9. import android.util.AttributeSet;  
    10. import android.util.DisplayMetrics;  
    11. import android.util.FloatMath;  
    12. import android.view.MotionEvent;  
    13. import android.view.View;  
    14. import android.widget.ImageView;  
    15.   
    16. public class MyImageView extends ImageView{  
    17.     Matrix matrix = new Matrix();  
    18.     Matrix savedMatrix = new Matrix();  
    19.     /**位图对象*/  
    20.     private Bitmap bitmap = null;  
    21.     /** 屏幕的分辨率*/  
    22.     private DisplayMetrics dm;  
    23.   
    24.     /** 最小缩放比例*/  
    25.     float minScaleR = 1.0f;  
    26.       
    27.     /** 最大缩放比例*/  
    28.     static final float MAX_SCALE = 15f;  
    29.   
    30.     /** 初始状态*/  
    31.     static final int NONE = 0;  
    32.     /** 拖动*/  
    33.     static final int DRAG = 1;  
    34.     /** 缩放*/  
    35.     static final int ZOOM = 2;  
    36.       
    37.     /** 当前模式*/  
    38.     int mode = NONE;  
    39.   
    40.     /** 存储float类型的x,y值,就是你点下的坐标的X和Y*/  
    41.     PointF prev = new PointF();  
    42.     PointF mid = new PointF();  
    43.     float dist = 1f;  
    44.       
    45.     public MyImageView(Context context) {  
    46.         super(context);  
    47.         setupView();  
    48.     }  
    49.       
    50.     public MyImageView(Context context, AttributeSet attrs) {  
    51.         super(context, attrs);  
    52.         setupView();  
    53.     }  
    54.       
    55.       
    56.     public void setupView(){  
    57.         Context context = getContext();  
    58.         //获取屏幕分辨率,需要根据分辨率来使用图片居中  
    59.         dm = context.getResources().getDisplayMetrics();  
    60.           
    61.         //根据MyImageView来获取bitmap对象  
    62.         BitmapDrawable bd = (BitmapDrawable)this.getDrawable();  
    63.         if(bd != null){  
    64.             bitmap = bd.getBitmap();  
    65.         }  
    66.           
    67.         //设置ScaleType为ScaleType.MATRIX,这一步很重要  
    68.         this.setScaleType(ScaleType.MATRIX);  
    69.         this.setImageBitmap(bitmap);  
    70.           
    71.         //bitmap为空就不调用center函数  
    72.         if(bitmap != null){  
    73.             center(true, true);  
    74.         }  
    75.         this.setImageMatrix(matrix);  
    76.         this.setOnTouchListener(new OnTouchListener() {  
    77.             @Override  
    78.             public boolean onTouch(View v, MotionEvent event) {  
    79.                  switch (event.getAction() & MotionEvent.ACTION_MASK) {  
    80.                     // 主点按下  
    81.                     case MotionEvent.ACTION_DOWN:  
    82.                         savedMatrix.set(matrix);  
    83.                         prev.set(event.getX(), event.getY());  
    84.                         mode = DRAG;  
    85.                         break;  
    86.                     // 副点按下  
    87.                     case MotionEvent.ACTION_POINTER_DOWN:  
    88.                         dist = spacing(event);  
    89.                         // 如果连续两点距离大于10,则判定为多点模式  
    90.                         if (spacing(event) > 10f) {  
    91.                             savedMatrix.set(matrix);  
    92.                             midPoint(mid, event);  
    93.                             mode = ZOOM;  
    94.                         }  
    95.                         break;  
    96.                     case MotionEvent.ACTION_UP:{  
    97.                         break;  
    98.                     }  
    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.                     MyImageView.this.setImageMatrix(matrix);  
    119.                     CheckView();  
    120.                     return true;  
    121.             }  
    122.         });  
    123.     }  
    124.       
    125.       
    126.     /** 
    127.      * 横向、纵向居中 
    128.      */  
    129.     protected void center(boolean horizontal, boolean vertical) {  
    130.         Matrix m = new Matrix();  
    131.         m.set(matrix);  
    132.         RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());  
    133.         m.mapRect(rect);  
    134.   
    135.         float height = rect.height();  
    136.         float width = rect.width();  
    137.   
    138.         float deltaX = 0, deltaY = 0;  
    139.   
    140.         if (vertical) {  
    141.             // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移  
    142.             int screenHeight = dm.heightPixels;  
    143.             if (height < screenHeight) {  
    144.                 deltaY = (screenHeight - height) / 2 - rect.top;  
    145.             } else if (rect.top > 0) {  
    146.                 deltaY = -rect.top;  
    147.             } else if (rect.bottom < screenHeight) {  
    148.                 deltaY = this.getHeight() - rect.bottom;  
    149.             }  
    150.         }  
    151.   
    152.         if (horizontal) {  
    153.             int screenWidth = dm.widthPixels;  
    154.             if (width < screenWidth) {  
    155.                 deltaX = (screenWidth - width) / 2 - rect.left;  
    156.             } else if (rect.left > 0) {  
    157.                 deltaX = -rect.left;  
    158.             } else if (rect.right < screenWidth) {  
    159.                 deltaX = screenWidth - rect.right;  
    160.             }  
    161.         }  
    162.         matrix.postTranslate(deltaX, deltaY);  
    163.     }  
    164.   
    165.       
    166.     /** 
    167.      * 限制最大最小缩放比例,自动居中 
    168.      */  
    169.     private void CheckView() {  
    170.         float p[] = new float[9];  
    171.         matrix.getValues(p);  
    172.         if (mode == ZOOM) {  
    173.             if (p[0] < minScaleR) {  
    174.                 //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR);  
    175.                 matrix.setScale(minScaleR, minScaleR);  
    176.             }  
    177.             if (p[0] > MAX_SCALE) {  
    178.                 //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE);  
    179.                 matrix.set(savedMatrix);  
    180.             }  
    181.         }  
    182.         center(true, true);  
    183.     }  
    184.       
    185.       
    186.     /** 
    187.      * 两点的距离 
    188.      */  
    189.     private float spacing(MotionEvent event) {  
    190.         float x = event.getX(0) - event.getX(1);  
    191.         float y = event.getY(0) - event.getY(1);  
    192.         return FloatMath.sqrt(x * x + y * y);  
    193.     }  
    194.   
    195.     /** 
    196.      * 两点的中点 
    197.      */  
    198.     private void midPoint(PointF point, MotionEvent event) {  
    199.         float x = event.getX(0) + event.getX(1);  
    200.         float y = event.getY(0) + event.getY(1);  
    201.         point.set(x / 2, y / 2);  
    202.     }  
    203. }  
    布局文件需要注意了,使用 <com.example.myimageview.MyImageView></com.example.myimageview.MyImageView>标签,怕一些新手不知道,别怪我啰嗦
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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.     <com.example.myimageview.MyImageView  
    6.         android:id="@+id/imageview"  
    7.         android:layout_width="fill_parent"  
    8.         android:layout_height="fill_parent"  
    9.         android:src="@drawable/item" >  
    10.     </com.example.myimageview.MyImageView>  
    11. </RelativeLayout>  

    新建一个MainActivity咯,

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. package com.example.myimageview;  
    2.   
    3. import android.app.Activity;  
    4. import android.os.Bundle;  
    5.   
    6. public class MainActivity extends Activity {  
    7.   
    8.     @Override  
    9.     protected void onCreate(Bundle savedInstanceState) {  
    10.         super.onCreate(savedInstanceState);  
    11.         setContentView(R.layout.activity_main);  
    12.         MyImageView myImageView = (MyImageView)findViewById(R.id.imageview);  
    13.         myImageView.setImageDrawable(getResources().getDrawable(R.drawable.item1));  
    14.     }  
    15. }  
    项目源码,点击下载
  • 相关阅读:
    五大常用算法之一:分治算法
    【Redis实战】双写一致性问题和解决方案
    大厂面试官喜欢这样问Redis,双写一致性、并发竞争、线程模型,我整理好了
    布隆过滤器的原理以及使用场景
    死磕 Redis- 布隆过滤器
    布隆过滤器(Bloom Filter)原理及实现
    布隆过滤器(亿级数据过滤算法)
    Java防止SQL注入2(通过filter过滤器功能进行拦截)
    java项目中如何防止sql注入
    java如入防止sql注入
  • 原文地址:https://www.cnblogs.com/bigben0123/p/4239594.html
Copyright © 2011-2022 走看看