当前位置: 移动技术网 > 移动技术>移动开发>Android > Android手势滑动实现ImageView缩放图片大小

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文推出了两种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);
  }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网