Android手势滑动实现ImageView缩放图片大小
程序员文章站
2024-02-23 16:26:46
本文推出了两种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); } }