欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android手势滑动实现ImageView缩放图片大小

程序员文章站 2024-02-19 22:50:13
本文推出了两种android手势实现imageview缩放图片大小的方法,分享给大家供大家参考,具体内容如下 方法一: 将以下代码写到mulitpointtouchli...

本文推出了两种android手势实现imageview缩放图片大小的方法,分享给大家供大家参考,具体内容如下

方法一:
将以下代码写到mulitpointtouchlistener.java中,然后对你相应的图片进行ontouchlistener。
例如:imageview.setontouchlistener(new mulitpointtouchlistener ());
在xml中要将imageview的缩放格式改成matrix
例如:android:scaletype="matrix"
这样就可以实现图片的缩放了
下面是mulitpointtouchlistener.java代码:

public class mulitpointtouchlistener implements ontouchlistener {  
    private static final string tag = "touch";  
    // these matrices will be used to move and zoom image  
    matrix matrix = new matrix();  
    matrix savedmatrix = new matrix();  
 
    // we can be in one of these 3 states  
    static final int none = 0;  
    static final int drag = 1;  
    static final int zoom = 2;  
    int mode = none;  
 
    // remember some things for zooming  
    pointf start = new pointf();  
    pointf mid = new pointf();  
    float olddist = 1f;  
 
    @override 
    public boolean ontouch(view v, motionevent event) {  
 
        imageview view = (imageview) v;  
        // log.e("view_width",  
        // view.getimagematrix()..tostring()+"*"+v.getwidth());  
        // dump touch event to log  
        dumpevent(event);  
 
        // handle touch events here...  
        switch (event.getaction() & motionevent.action_mask) {  
        case motionevent.action_down:  
 
            matrix.set(view.getimagematrix());  
            savedmatrix.set(matrix);  
            start.set(event.getx(), event.gety());  
            //log.d(tag, "mode=drag");  
            mode = drag;  
 
             
            //log.d(tag, "mode=none");  
            break;  
        case motionevent.action_pointer_down:  
            olddist = spacing(event);  
            //log.d(tag, "olddist=" + olddist);  
            if (olddist > 10f) {  
                savedmatrix.set(matrix);  
                midpoint(mid, event);  
                mode = zoom;  
                //log.d(tag, "mode=zoom");  
            }  
            break;  
        case motionevent.action_up:  
        case motionevent.action_pointer_up:  
            mode = none;  
            //log.e("view.getwidth", view.getwidth() + "");  
            //log.e("view.getheight", view.getheight() + "");  
 
            break;  
        case motionevent.action_move:  
            if (mode == drag) {  
                // ...  
                matrix.set(savedmatrix);  
                matrix.posttranslate(event.getx() - start.x, event.gety()  
                        - start.y);  
            } else if (mode == zoom) {  
                float newdist = spacing(event);  
                //log.d(tag, "newdist=" + newdist);  
                if (newdist > 10f) {  
                    matrix.set(savedmatrix);  
                    float scale = newdist / olddist;  
                    matrix.postscale(scale, scale, mid.x, mid.y);  
                }  
            }  
            break;  
        }  
 
        view.setimagematrix(matrix);  
        return true; // indicate event was handled  
    }  
 
    private void dumpevent(motionevent event) {  
        string names[] = { "down", "up", "move", "cancel", "outside",  
                "pointer_down", "pointer_up", "7?", "8?", "9?" };  
        stringbuilder sb = new stringbuilder();  
        int action = event.getaction();  
        int actioncode = action & motionevent.action_mask;  
        sb.append("event action_").append(names[actioncode]);  
        if (actioncode == motionevent.action_pointer_down  
                || actioncode == motionevent.action_pointer_up) {  
            sb.append("(pid ").append(  
                    action >> motionevent.action_pointer_id_shift);  
            sb.append(")");  
        }  
        sb.append("[");  
        for (int i = 0; i < event.getpointercount(); i++) {  
            sb.append("#").append(i);  
            sb.append("(pid ").append(event.getpointerid(i));  
            sb.append(")=").append((int) event.getx(i));  
            sb.append(",").append((int) event.gety(i));  
            if (i + 1 < event.getpointercount())  
                sb.append(";");  
        }  
        sb.append("]");  
        //log.d(tag, sb.tostring());  
    }  
 
     
    private float spacing(motionevent event) {  
        float x = event.getx(0) - event.getx(1);  
        float y = event.gety(0) - event.gety(1);  
        return floatmath.sqrt(x * x + y * y);  
    }  
 
     
    private void midpoint(pointf point, motionevent event) {  
        float x = event.getx(0) + event.getx(1);  
        float y = event.gety(0) + event.gety(1);  
        point.set(x / 2, y / 2);  
    }  
} 


方法二:自定义一个imageview,例如touchimageview:

import android.content.context;
import android.graphics.matrix;
import android.graphics.pointf;
import android.graphics.drawable.drawable;
import android.util.attributeset;
import android.util.log;
import android.view.motionevent;
import android.view.scalegesturedetector;
import android.view.view;
import android.widget.imageview;

public class touchimageview extends imageview {

  matrix matrix;

  // we can be in one of these 3 states
  static final int none = 0;
  static final int drag = 1;
  static final int zoom = 2;
  int mode = none;

  // remember some things for zooming
  pointf last = new pointf();
  pointf start = new pointf();
  float minscale = 1f;
  float maxscale = 3f;
  float[] m;


  int viewwidth, viewheight;
  static final int click = 3;
  float savescale = 1f;
  protected float origwidth, origheight;
  int oldmeasuredwidth, oldmeasuredheight;


  scalegesturedetector mscaledetector;

  context context;

  public touchimageview(context context) {
    super(context);
    sharedconstructing(context);
  }

  public touchimageview(context context, attributeset attrs) {
    super(context, attrs);
    sharedconstructing(context);
  }
  
  private void sharedconstructing(context context) {
    super.setclickable(true);
    this.context = context;
    mscaledetector = new scalegesturedetector(context, new scalelistener());
    matrix = new matrix();
    m = new float[9];
    setimagematrix(matrix);
    setscaletype(scaletype.matrix);

    setontouchlistener(new ontouchlistener() {

      @override
      public boolean ontouch(view v, motionevent event) {
        mscaledetector.ontouchevent(event);
        pointf curr = new pointf(event.getx(), event.gety());

        switch (event.getaction()) {
          case motionevent.action_down:
           last.set(curr);
            start.set(last);
            mode = drag;
            break;
            
          case motionevent.action_move:
            if (mode == drag) {
              float deltax = curr.x - last.x;
              float deltay = curr.y - last.y;
              float fixtransx = getfixdragtrans(deltax, viewwidth, origwidth * savescale);
              float fixtransy = getfixdragtrans(deltay, viewheight, origheight * savescale);
              matrix.posttranslate(fixtransx, fixtransy);
              fixtrans();
              last.set(curr.x, curr.y);
            }
            break;

          case motionevent.action_up:
            mode = none;
            int xdiff = (int) math.abs(curr.x - start.x);
            int ydiff = (int) math.abs(curr.y - start.y);
            if (xdiff < click && ydiff < click)
              performclick();
            break;

          case motionevent.action_pointer_up:
            mode = none;
            break;
        }
        
        setimagematrix(matrix);
        invalidate();
        return true; // indicate event was handled
      }

    });
  }

  public void setmaxzoom(float x) {
    maxscale = x;
  }

  private class scalelistener extends scalegesturedetector.simpleonscalegesturelistener {
    @override
    public boolean onscalebegin(scalegesturedetector detector) {
      mode = zoom;
      return true;
    }

    @override
    public boolean onscale(scalegesturedetector detector) {
      float mscalefactor = detector.getscalefactor();
      float origscale = savescale;
      savescale *= mscalefactor;
      if (savescale > maxscale) {
        savescale = maxscale;
        mscalefactor = maxscale / origscale;
      } else if (savescale < minscale) {
        savescale = minscale;
        mscalefactor = minscale / origscale;
      }

      if (origwidth * savescale <= viewwidth || origheight * savescale <= viewheight)
        matrix.postscale(mscalefactor, mscalefactor, viewwidth / 2, viewheight / 2);
      else
        matrix.postscale(mscalefactor, mscalefactor, detector.getfocusx(), detector.getfocusy());

      fixtrans();
      return true;
    }
  }

  void fixtrans() {
    matrix.getvalues(m);
    float transx = m[matrix.mtrans_x];
    float transy = m[matrix.mtrans_y];
    
    float fixtransx = getfixtrans(transx, viewwidth, origwidth * savescale);
    float fixtransy = getfixtrans(transy, viewheight, origheight * savescale);

    if (fixtransx != 0 || fixtransy != 0)
      matrix.posttranslate(fixtransx, fixtransy);
  }

  float getfixtrans(float trans, float viewsize, float contentsize) {
    float mintrans, maxtrans;

    if (contentsize <= viewsize) {
      mintrans = 0;
      maxtrans = viewsize - contentsize;
    } else {
      mintrans = viewsize - contentsize;
      maxtrans = 0;
    }

    if (trans < mintrans)
      return -trans + mintrans;
    if (trans > maxtrans)
      return -trans + maxtrans;
    return 0;
  }
  
  float getfixdragtrans(float delta, float viewsize, float contentsize) {
    if (contentsize <= viewsize) {
      return 0;
    }
    return delta;
  }

  @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    super.onmeasure(widthmeasurespec, heightmeasurespec);
    viewwidth = measurespec.getsize(widthmeasurespec);
    viewheight = measurespec.getsize(heightmeasurespec);
    
    //
    // rescales image on rotation
    //
    if (oldmeasuredheight == viewwidth && oldmeasuredheight == viewheight
        || viewwidth == 0 || viewheight == 0)
      return;
    oldmeasuredheight = viewheight;
    oldmeasuredwidth = viewwidth;

    if (savescale == 1) {
      //fit to screen.
      float scale;

      drawable drawable = getdrawable();
      if (drawable == null || drawable.getintrinsicwidth() == 0 || drawable.getintrinsicheight() == 0)
        return;
      int bmwidth = drawable.getintrinsicwidth();
      int bmheight = drawable.getintrinsicheight();
      
      log.d("bmsize", "bmwidth: " + bmwidth + " bmheight : " + bmheight);

      float scalex = (float) viewwidth / (float) bmwidth;
      float scaley = (float) viewheight / (float) bmheight;
      scale = math.min(scalex, scaley);
      matrix.setscale(scale, scale);

      // center the image
      float redundantyspace = (float) viewheight - (scale * (float) bmheight);
      float redundantxspace = (float) viewwidth - (scale * (float) bmwidth);
      redundantyspace /= (float) 2;
      redundantxspace /= (float) 2;

      matrix.posttranslate(redundantxspace, redundantyspace);

      origwidth = viewwidth - 2 * redundantxspace;
      origheight = viewheight - 2 * redundantyspace;
      setimagematrix(matrix);
    }
    fixtrans();
  }
}

然后在我们的activity中就可以直接使用了:

public class touchimageviewactivity extends activity {
  /** called when the activity is first created. */
  @override
  public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.main);
    touchimageview img = (touchimageview) findviewbyid(r.id.snoop);
    img.setimageresource(r.drawable.snoopy);
    img.setmaxzoom(4f);
  }
}