自定义类继承ImageView 实现多点图片触碰的拖动和缩放

来源:互联网 发布:推荐手机桌面软件 编辑:程序博客网 时间:2024/05/01 22:20

自定义类继承ImageView 实现多点图片触碰的拖动和缩放

最近的一个android 项目中,客户要求在查看拍照上传的图片时,可以对图片进行多点触控的拖拽、放大、缩小等操作。网上的范例都不怎么好,实现的效果差强人意。

下面说说我的方案:

步骤一:自定义一个View,该View继承自ImageView。在该View中实现多点触控的拖拽、缩放等功能。

步骤二:像使用ImageView那样,在XML中引入该View。当然也可以动态创建该View然后添加到容器组件中。

 

一、自定义TouchView继承ImageView

Java代码  收藏代码
  1. package com.hzunitech.xcgk.ui;  
  2.   
  3. import android.content.Context;     
  4. import android.util.AttributeSet;  
  5. import android.util.FloatMath;     
  6. import android.view.MotionEvent;     
  7. import android.view.animation.TranslateAnimation;     
  8. import android.widget.ImageView;     
  9. /**   
  10.  * 继承ImageView 实现了多点触碰的拖动和缩放   
  11.  * @author lihua     
  12.  */     
  13. public class TouchView extends ImageView {  
  14.       
  15.   
  16.     static final int NONE = 0;     
  17.     static final int DRAG = 1;     //拖动中      
  18.     static final int ZOOM = 2;     //缩放中      
  19.     static final int BIGGER = 3;   //放大ing      
  20.     static final int SMALLER = 4;  //缩小ing      
  21.     private int mode = NONE;       //当前的事件       
  22.      
  23.     private float beforeLenght;   //两触点距离      
  24.     private float afterLenght;    //两触点距离      
  25.     private float scale = 0.04f;  //缩放的比例 X Y方向都是这个值 越大缩放的越快      
  26.         
  27.     private int screenW;     
  28.     private int screenH;     
  29.          
  30.     /*处理拖动 变量 */     
  31.     private int start_x;     
  32.     private int start_y;     
  33.     private int stop_x ;     
  34.     private int stop_y ;     
  35.          
  36.     private TranslateAnimation trans; //处理超出边界的动画      
  37.       
  38.     /** 
  39.      * 默认构造函数 
  40.      * @param context 
  41.      */  
  42.     public TouchView(Context context){  
  43.         super(context);  
  44.     }  
  45.     /** 
  46.      * 该构造方法在静态引入XML文件中是必须的 
  47.      * @param context 
  48.      * @param paramAttributeSet 
  49.      */  
  50.     public TouchView(Context context,AttributeSet paramAttributeSet){  
  51.         super(context,paramAttributeSet);  
  52.     }  
  53.     /** 
  54.      * 该构造函数在动态创建时,指定图片的初始高宽 
  55.      * @param context 
  56.      * @param w 
  57.      * @param h 
  58.      */  
  59.     public TouchView(Context context,int w,int h) {     
  60.         super(context);     
  61.         this.setPadding(0000);     
  62.         screenW = w;     
  63.         screenH = h;     
  64.     }     
  65.          
  66.     /**   
  67.      * 就算两点间的距离   
  68.      */     
  69.     private float spacing(MotionEvent event) {     
  70.         float x = event.getX(0) - event.getX(1);     
  71.         float y = event.getY(0) - event.getY(1);     
  72.         return FloatMath.sqrt(x * x + y * y);     
  73.     }     
  74.          
  75.     /**   
  76.      * 处理触碰..   
  77.      */     
  78.     @Override     
  79.     public boolean onTouchEvent(MotionEvent event)     
  80.     {        
  81.         switch (event.getAction() & MotionEvent.ACTION_MASK) {     
  82.         case MotionEvent.ACTION_DOWN:     
  83.                 mode = DRAG;     
  84.                 stop_x = (int) event.getRawX();     
  85.                 stop_y = (int) event.getRawY();     
  86.                 start_x = (int) event.getX();     
  87.                 start_y = stop_y - this.getTop();     
  88.                 if(event.getPointerCount()==2)     
  89.                     beforeLenght = spacing(event);     
  90.                 break;     
  91.         case MotionEvent.ACTION_POINTER_DOWN:     
  92.                 if (spacing(event) > 10f) {     
  93.                         mode = ZOOM;     
  94.                         beforeLenght = spacing(event);     
  95.                 }     
  96.                 break;     
  97.         case MotionEvent.ACTION_UP:     
  98.             /*判断是否超出范围     并处理*/     
  99.                 int disX = 0;     
  100.                 int disY = 0;     
  101.                 if(getHeight()<=screenH || this.getTop()<0)     
  102.                 {     
  103.                     if(this.getTop()<0 )     
  104.                     {     
  105.                         int dis = getTop();     
  106.                         this.layout(this.getLeft(), 0this.getRight(), 0 + this.getHeight());     
  107.                         disY = dis - getTop();     
  108.                     }     
  109.                     else if(this.getBottom()>screenH)     
  110.                     {     
  111.                         disY = getHeight()- screenH+getTop();     
  112.                         this.layout(this.getLeft(), screenH-getHeight(), this.getRight(), screenH);     
  113.                     }     
  114.                 }     
  115.                 if(getWidth()<=screenW)     
  116.                 {     
  117.                     if(this.getLeft()<0)     
  118.                     {     
  119.                         disX = getLeft();     
  120.                         this.layout(0this.getTop(), 0+getWidth(), this.getBottom());     
  121.                     }     
  122.                     else if(this.getRight()>screenW)     
  123.                     {     
  124.                         disX = getWidth()-screenW+getLeft();     
  125.                         this.layout(screenW-getWidth(), this.getTop(), screenW, this.getBottom());     
  126.                     }     
  127.                 }     
  128.                 if(disX!=0 || disY!=0)     
  129.                 {     
  130.                     trans = new TranslateAnimation(disX, 0, disY, 0);     
  131.                     trans.setDuration(500);     
  132.                     this.startAnimation(trans);     
  133.                 }     
  134.                 mode = NONE;     
  135.                 break;     
  136.         case MotionEvent.ACTION_POINTER_UP:     
  137.                 mode = NONE;     
  138.                 break;     
  139.         case MotionEvent.ACTION_MOVE:     
  140.                 /*处理拖动*/     
  141.                 if (mode == DRAG) {     
  142.                     if(Math.abs(stop_x-start_x-getLeft())<88 && Math.abs(stop_y - start_y-getTop())<85)     
  143.                     {     
  144.                         this.setPosition(stop_x - start_x, stop_y - start_y, stop_x + this.getWidth() - start_x, stop_y - start_y + this.getHeight());                   
  145.                         stop_x = (int) event.getRawX();     
  146.                         stop_y = (int) event.getRawY();     
  147.                     }     
  148.                 }      
  149.                 /*处理缩放*/     
  150.                 else if (mode == ZOOM) {     
  151.                     if(spacing(event)>10f)     
  152.                     {     
  153.                         afterLenght = spacing(event);     
  154.                         float gapLenght = afterLenght - beforeLenght;                          
  155.                         if(gapLenght == 0) {       
  156.                            break;     
  157.                         }     
  158.                         else if(Math.abs(gapLenght)>5f)     
  159.                         {     
  160.                             if(gapLenght>0) {    
  161.                                   
  162.                                 this.setScale(scale,BIGGER);        
  163.                             }else {       
  164.                                 this.setScale(scale,SMALLER);        
  165.                             }                                  
  166.                             beforeLenght = afterLenght;      
  167.                         }     
  168.                     }     
  169.                 }     
  170.                 break;     
  171.         }     
  172.         return true;         
  173.     }   
  174.       
  175.       
  176.     /**   
  177.      * 实现处理缩放   
  178.      */     
  179.     private void setScale(float temp,int flag) {        
  180.              
  181.         if(flag==BIGGER) {        
  182.             this.setFrame(this.getLeft()-(int)(temp*this.getWidth()),         
  183.                           this.getTop()-(int)(temp*this.getHeight()),         
  184.                           this.getRight()+(int)(temp*this.getWidth()),         
  185.                           this.getBottom()+(int)(temp*this.getHeight()));           
  186.         }else if(flag==SMALLER){        
  187.             this.setFrame(this.getLeft()+(int)(temp*this.getWidth()),         
  188.                           this.getTop()+(int)(temp*this.getHeight()),         
  189.                           this.getRight()-(int)(temp*this.getWidth()),         
  190.                           this.getBottom()-(int)(temp*this.getHeight()));        
  191.         }        
  192.     }     
  193.          
  194.     /**   
  195.      * 实现处理拖动   
  196.      */     
  197.     private void setPosition(int left,int top,int right,int bottom) {       
  198.         this.layout(left,top,right,bottom);                  
  199.     }     
  200. }  

 

二、在XML文件中引入TouchView。

在xml中引入TouchView和引入其父类ImageView是一样的。

Xml代码  收藏代码
  1. <ImageView  
  2.        android:id="@+id/drawing"  
  3.        android:layout_width="fill_parent"  
  4.        android:layout_height="fill_parent" >  
  5.    </ImageView>  
 
Xml代码  收藏代码
  1. <com.hzunitech.xcgk.ui.TouchView  
  2.        android:id="@+id/drawing"  
  3.        android:layout_width="fill_parent"  
  4.        android:layout_height="fill_parent"   
  5.        android:layout_marginTop="50px"  
  6.        android:gravity="center">  
  7.    </com.hzunitech.xcgk.ui.TouchView>  

 在Activity中,为找到该组件,并为其动态设置图片。

Java代码  收藏代码
  1. TouchView drawing = (TouchView)findViewById(R.id.drawing);  
  2. //獲得網絡url上的一個圖片  
  3. Bitmap img = AvdUtils.getHttpBitmap(Constants.URL_PREFIX+takan.getFileName());    
  4. drawing.setImageBitmap(img); 

参考自:http://hbxflihua.iteye.com/blog/1485032
0 0
原创粉丝点击