imageview - Add limit to zoom-in and zoom-out in android -
i have imageview can zoomed. have code works well, problem want add limit maximum , minimum zooming levels.
import android.annotation.targetapi; import android.app.actionbar; import android.app.activity; import android.graphics.matrix; import android.graphics.pointf; import android.os.build; import android.os.bundle; import android.util.floatmath; import android.util.log; import android.view.menuitem; import android.view.motionevent; import android.view.view; import android.view.view.ontouchlistener; import android.widget.imageview; @targetapi(build.version_codes.honeycomb) public class reach extends activity implements ontouchlistener { private static final string tag = "touch"; @suppresswarnings("unused") private static final float min_zoom = 1f,max_zoom = 1f; // these matrices used scale points of image matrix matrix = new matrix(); matrix savedmatrix = new matrix(); // 3 states (events) user trying perform static final int none = 0; static final int drag = 1; static final int zoom = 2; int mode = none; // these pointf objects used record point(s) user touching pointf start = new pointf(); pointf mid = new pointf(); float olddist = 1f; @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub super.oncreate(savedinstancestate); setcontentview(r.layout.reach_us); int currentapiversion = android.os.build.version.sdk_int; if (currentapiversion >= android.os.build.version_codes.honeycomb) { // run code specific api levels above honeycomb (api 11+) actionbar actionbar = getactionbar(); actionbar.setdisplayhomeasupenabled(true); } imageview view=(imageview)findviewbyid(r.id.map); view.setontouchlistener(this); } @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case android.r.id.home: { this.finish(); return true; } default: return super.onoptionsitemselected(item); } } @override public boolean ontouch(view v, motionevent event) { imageview view = (imageview) v; view.setscaletype(imageview.scaletype.matrix); float scale; dumpevent(event); // handle touch events here... switch (event.getaction() & motionevent.action_mask) { case motionevent.action_down: // first finger down savedmatrix.set(matrix); start.set(event.getx(), event.gety()); log.d(tag, "mode=drag"); // write logcat mode = drag; break; case motionevent.action_up: // first finger lifted case motionevent.action_pointer_up: // second finger lifted mode = none; log.d(tag, "mode=none"); break; case motionevent.action_pointer_down: // first , second finger down olddist = spacing(event); log.d(tag, "olddist=" + olddist); if (olddist > 5f) { savedmatrix.set(matrix); midpoint(mid, event); mode = zoom; log.d(tag, "mode=zoom"); } break; case motionevent.action_move: if (mode == drag) { matrix.set(savedmatrix); matrix.posttranslate(event.getx() - start.x, event.gety() - start.y); // create transformation in matrix of points } else if (mode == zoom) { // pinch zooming float newdist = spacing(event); log.d(tag, "newdist=" + newdist); if (newdist > 5f) { matrix.set(savedmatrix); scale = newdist / olddist; // setting scaling of // matrix...if scale > 1 means // zoom in...if scale < 1 means // zoom out matrix.postscale(scale, scale, mid.x, mid.y); } } break; } view.setimagematrix(matrix); // display transformation on screen return true; // indicate event handled } /* * -------------------------------------------------------------------------- * method: spacing parameters: motionevent returns: float description: * checks spacing between 2 fingers on touch * ---------------------------------------------------- */ 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); } /* * -------------------------------------------------------------------------- * method: midpoint parameters: pointf object, motionevent returns: void * description: calculates midpoint between 2 fingers * ------------------------------------------------------------ */ 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); } /** show event in logcat view, debugging */ 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("["); (int = 0; < 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("touch events ---------", sb.tostring()); } }
i have seen lot of question & answers linked this, no 1 helps me. please give me solution. in advance
i got solution this. not seems perfect one. add methods given below after switch cases , before view.setimagematrix(matrix);
here methods:
private void limitzoom(matrix m) { float[] values = new float[9]; m.getvalues(values); float scalex = values[matrix.mscale_x]; float scaley = values[matrix.mscale_y]; if(scalex > max_zoom) { scalex = max_zoom; } else if(scalex < min_zoom) { scalex = min_zoom; } if(scaley > max_zoom) { scaley = max_zoom; } else if(scaley < min_zoom) { scaley = min_zoom; } values[matrix.mscale_x] = scalex; values[matrix.mscale_y] = scaley; m.setvalues(values); } private void limitdrag(matrix m) { float[] values = new float[9]; m.getvalues(values); float transx = values[matrix.mtrans_x]; float transy = values[matrix.mtrans_y]; float scalex = values[matrix.mscale_x]; float scaley = values[matrix.mscale_y]; imageview iv = (imageview)findviewbyid(r.id.map); rect bounds = iv.getdrawable().getbounds(); int viewwidth = getresources().getdisplaymetrics().widthpixels; int viewheight = getresources().getdisplaymetrics().heightpixels; int width = bounds.right - bounds.left; int height = bounds.bottom - bounds.top; float minx = (-width + 20) * scalex; float miny = (-height + 20) * scaley; if(transx > (viewwidth - 20)) { transx = viewwidth - 20; } else if(transx < minx) { transx = minx; } if(transy > (viewheight - 80)) { transy = viewheight - 80; } else if(transy < miny) { transy = miny; } values[matrix.mtrans_x] = transx; values[matrix.mtrans_y] = transy; m.setvalues(values); }
is there other solution better one?
Comments
Post a Comment