Learn to slide the android gesture, Multi-Touch Zoom to reduce the picture, share for everyone to refer to, the specific code as follows
1. The layout file is as follows Main.xml
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
android:layout_width=" fill_parent "
android:layout_height=" fill_parent "
android:o" rientation= "Vertical" >
<!--referencing custom controls-->
<com.ymw.zoomimage.zoomimageview
android:id= "@+ Id/image "
android:layout_width=" wrap_content "
android:layout_height=" wrap_content ">
</ Com.ymw.zoomimage.zoomimageview>
</LinearLayout>
2. Custom zoom Picture Control Zoomimageview.java Code:
Package com.ymw.zoomimage;
Import java.util.Observable;
Import Java.util.Observer;
Import Android.content.Context;
Import Android.graphics.Bitmap;
Import Android.graphics.Canvas;
Import Android.graphics.Paint;
Import Android.graphics.Rect;
Import Android.util.AttributeSet;
Import Android.util.Log;
Import android.view.MotionEvent;
Import Android.view.View; public class Zoomimageview extends View implements Observer {/** Paint object used when drawing bitmap. * * Private fin
Al Paint mpaint = new Paint (Paint.filter_bitmap_flag); /** Rectangle Used (and re-used) for cropping source image.
* Private final Rect mrectsrc = new Rect (); /** Rectangle Used (and re-used) for specifying drawing area on canvas.
* Private final Rect mrectdst = new Rect ();
/** Object Holding Aspect quotient * * Private final aspectquotient maspectquotient = new Aspectquotient (); /** the bitmap that we ' re zooming in, and drawing on the screen.
* * Private Bitmap Mbitmap; /** State of the zoom.
*/ Private Zoomstate mstate;
Private Basiczoomcontrol Mzoomcontrol;
Private Basiczoomlistener Mzoomlistener;
Public Zoomimageview (context, AttributeSet attrs) {Super (context, attrs);
Mzoomcontrol = new Basiczoomcontrol ();
Mzoomlistener = new Basiczoomlistener ();
Mzoomlistener.setzoomcontrol (Mzoomcontrol);
Setzoomstate (Mzoomcontrol.getzoomstate ());
Setontouchlistener (Mzoomlistener);
Mzoomcontrol.setaspectquotient (Getaspectquotient ());
public void Zoomimage (float f, float x, float y) {mzoomcontrol.zoom (f, x, y);
public void SetImage (Bitmap Bitmap) {mbitmap = Bitmap;
Maspectquotient.updateaspectquotient (GetWidth (), GetHeight (), Mbitmap.getwidth (), Mbitmap.getheight ());
Maspectquotient.notifyobservers ();
Invalidate ();
private void Setzoomstate (Zoomstate state) {if (mstate!= null) {mstate.deleteobserver (this);
} mstate = State;
Mstate.addobserver (this);
Invalidate (); Private Aspectquotient GetaspectquotieNT () {return maspectquotient; @Override protected void OnDraw (Canvas Canvas) {if mbitmap!= null && mstate!= null) {LOG.D ("Zoomim
Ageview "," OnDraw ");
Final float aspectquotient = Maspectquotient.get ();
Final int viewwidth = GetWidth ();
Final int viewheight = GetHeight ();
Final int bitmapwidth = Mbitmap.getwidth ();
Final int bitmapheight = Mbitmap.getheight ();
LOG.D ("Zoomimageview", "viewwidth =" + viewwidth);
LOG.D ("Zoomimageview", "viewheight =" + viewheight);
LOG.D ("Zoomimageview", "bitmapwidth =" + bitmapwidth);
LOG.D ("Zoomimageview", "bitmapheight =" + bitmapheight);
Final float Panx = Mstate.getpanx ();
Final float pany = Mstate.getpany ();
Final float ZOOMX = MSTATE.GETZOOMX (aspectquotient) * viewwidth/bitmapwidth;
Final float zoomy = mstate.getzoomy (aspectquotient) * viewheight/bitmapheight; Setup source and destination rectangles mrectsrc.left = (int) (Panx * bitmapwidth-viewwidth/(ZOOMX * 2));
Mrectsrc.top = (int) (Pany * Bitmapheight-viewheight/(Zoomy * 2));
Mrectsrc.right = (int) (mrectsrc.left + VIEWWIDTH/ZOOMX);
Mrectsrc.bottom = (int) (mrectsrc.top + viewheight/zoomy);
Mrectdst.left = GetLeft ();
Mrectdst.left = 0;
mrectdst.top = 0;
Mrectdst.right = GetRight ();
Mrectdst.right = GetWidth ();
Mrectdst.bottom = GetHeight ();
Adjust source Rectangle so that it fits within the source image.
if (Mrectsrc.left < 0) {Mrectdst.left + =-mrectsrc.left * ZOOMX;
Mrectsrc.left = 0;
} if (Mrectsrc.right > Bitmapwidth) {mrectdst.right-= (mrectsrc.right-bitmapwidth) * ZOOMX;
Mrectsrc.right = Bitmapwidth;
} if (Mrectsrc.top < 0) {mrectdst.top + =-mrectsrc.top * zoomy;
mrectsrc.top = 0;
} if (Mrectsrc.bottom > Bitmapheight) {mrectdst.bottom-= (mrectsrc.bottom-bitmapheight) * zoomy;
Mrectsrc.bottom = Bitmapheight;
} mrectdst.left = 0; Mrectdst.top = 0;
Mrectdst.right = Viewwidth;
Mrectdst.bottom = Viewheight;
LOG.D ("Zoomimageview", "mrectsrc.top" + mrectsrc.top);
LOG.D ("Zoomimageview", "Mrectsrc.bottom" + mrectsrc.bottom);
LOG.D ("Zoomimageview", "mrectsrc.left" + mrectsrc.left);
LOG.D ("Zoomimageview", "mrectsrc.right" + mrectsrc.right);
LOG.D ("Zoomimageview", "mrectdst.top" + mrectdst.top);
LOG.D ("Zoomimageview", "Mrectdst.bottom" + mrectdst.bottom);
LOG.D ("Zoomimageview", "mrectdst.left" + mrectdst.left);
LOG.D ("Zoomimageview", "mrectdst.right" + mrectdst.right);
Canvas.drawbitmap (Mbitmap, MRECTSRC, MRECTDST, Mpaint); } @Override protected void OnLayout (Boolean changed, int left, int. top, int right, int bottom) {super.onlayout
(changed, left, top, right, bottom);
Maspectquotient.updateaspectquotient (Right-left, Bottom-top, Mbitmap.getwidth (), Mbitmap.getheight ());
Maspectquotient.notifyobservers (); @Override public void Update (observable observable, objeCT data) {invalidate (); Private class Basiczoomlistener implements View.ontouchlistener {/** Zoom control to manipulate * * Private Basic
Zoomcontrol Mzoomcontrol;
Private float MFIRSTX =-1;
Private float mfirsty =-1;
Private float msecondx =-1;
Private float Msecondy =-1;
private int moldcounts = 0; /** * Sets The Zoom control to manipulate * @param control * Zoom control/public void Setzoomcont
Rol (Basiczoomcontrol control) {Mzoomcontrol = control;
public boolean Ontouch (View v., motionevent event) {switch (event.getaction ()) {case Motionevent.action_down:
moldcounts = 1;
MFIRSTX = Event.getx ();
Mfirsty = Event.gety ();
Break
Case Motionevent.action_move: {Float ffirstx = Event.getx ();
float ffirsty = event.gety ();
int ncounts = Event.getpointercount ();
if (1 = ncounts) {moldcounts = 1;
float dx = (FFIRSTX-MFIRSTX)/v.getwidth (); float dy = (ffirsty-mfIrsty)/V.getheight ();
Mzoomcontrol.pan (-DX,-dy);
else if (1 = moldcounts) {msecondx = Event.getx (Event.getpointerid (nCounts-1));
Msecondy = Event.gety (Event.getpointerid (nCounts-1));
Moldcounts = ncounts;
else {Float Fsecondx = event. GetX (Event.getpointerid (nCounts-1));
Float Fsecondy = event. GetY (Event.getpointerid (nCounts-1));
Double nlengthold = GetLength (Mfirstx, Mfirsty, Msecondx, Msecondy);
Double Nlengthnow = GetLength (Ffirstx, Ffirsty, Fsecondx, Fsecondy);
Float d = (float) ((nlengthnow-nlengthold)/V.getwidth ()); Mzoomcontrol.zoom ((float) Math.pow ((Ffirstx + fsecondx)/2/v.getwidth ()), ((Ffirsty + Fsecondy)
/2/v.getheight ()));
Msecondx = Fsecondx;
Msecondy = Fsecondy;
} MFIRSTX = Ffirstx;
Mfirsty = Ffirsty;
Break
} return true; Private double GetLength (float x1, float y1, float x2, float y2) {return math.sqrt (Math.pow (X1-X2, 2) + Math.pow (Y1-y2, 2)); } Private class Basiczoomcontrol implements Observer {/** Minimum zoom level limit * * private static final Floa
t min_zoom = 1;
/** Maximum Zoom Level limit * * Private static final float max_zoom = 16;
/** Zoom State under control/private final zoomstate mstate = new Zoomstate ();
/** Object Holding aspect quotient of view and content/private aspectquotient maspectquotient; /** * Set Reference Object holding aspect quotient * * @param aspectquotient * Object holding aspect Quotie NT */public void setaspectquotient (Aspectquotient aspectquotient) {if (maspectquotient!= null) {maspectquo
Tient.deleteobserver (this);
} maspectquotient = Aspectquotient;
Maspectquotient.addobserver (this);
/** * Get zoom state being controlled * * @return the Zoom state/public Zoomstate getzoomstate () {
return mstate;
}/** * Zoom * * @param f * Factor of Zoom to apply * @param x * X-coordinate of invariant position * @param y * Y-coordinate of invariant position/public void zoom (float f, float x, float Y) {//LOG.D ("Zoom", "Zoom F")
= "+ F");
Final float aspectquotient = Maspectquotient.get ();
Final float PREVZOOMX = MSTATE.GETZOOMX (aspectquotient);
Final float prevzoomy = mstate.getzoomy (aspectquotient);
Mstate.setzoom (Mstate.getzoom () * f);
Limitzoom ();
Final float NEWZOOMX = MSTATE.GETZOOMX (aspectquotient);
Final float newzoomy = mstate.getzoomy (aspectquotient); Pan to keep x and Y coordinate invariant Mstate.setpanx (Mstate.getpanx () + (X-. 5f) * (1f/prevzoomx-1f/n
EWZOOMX));
Mstate.setpany (Mstate.getpany () + (Y-. 5f) * (1f/prevzoomy-1f/newzoomy));
Limitpan ();
Mstate.notifyobservers (); /** * Pan * * @param DX * Amount to pan in x-dimension * @param dy * Amount to pan in Y-diMension */public void pan (float dx, float dy) {final float aspectquotient = Maspectquotient.get ();
Mstate.setpanx (Mstate.getpanx () + DX/MSTATE.GETZOOMX (aspectquotient));
Mstate.setpany (Mstate.getpany () + dy/mstate.getzoomy (aspectquotient));
Limitpan ();
Mstate.notifyobservers ();
}/** * Help function to figure out Max Delta's pan from center position.
* * @param ZOOM * Zoom value * @return Max delta of Pan */private float Getmaxpandelta (float zoom) {
Return Math.max (0f,. 5f * ((zoom-1)/zoom));
}/** * Force zoom to stay within limits/private void Limitzoom () {if (Mstate.getzoom () < Min_zoom) {
Mstate.setzoom (Min_zoom);
else if (Mstate.getzoom () > Max_zoom) {mstate.setzoom (max_zoom); }/** * Force pan to stay within limits/private void Limitpan () {final float aspectquotient = Maspec
Tquotient.get (); Final float ZOOMX = MSTATE.GETZOOMX (aspectquotiENT);
Final float zoomy = mstate.getzoomy (aspectquotient);
Final float Panminx =. 5f-getmaxpandelta (ZOOMX);
Final float Panmaxx =. 5f + getmaxpandelta (ZOOMX);
Final float Panminy =. 5f-getmaxpandelta (zoomy);
Final float Panmaxy =. 5f + getmaxpandelta (zoomy);
if (Mstate.getpanx () < Panminx) {Mstate.setpanx (Panminx);
} if (Mstate.getpanx () > Panmaxx) {mstate.setpanx (Panmaxx);
} if (Mstate.getpany () < Panminy) {Mstate.setpany (panminy);
} if (Mstate.getpany () > Panmaxy) {mstate.setpany (panmaxy); }//observable interface implementation public void update (observable observable, Object data) {Limitzoom ()
;
Limitpan (); } private class Aspectquotient extends observable {/** * Aspect quotient * * Private float Maspectquotient
;
Public methods/** * Gets Aspect Quotient * * @return the aspect quotient/public float get () {
return maspectquotient;
}
/** * Updates and recalculates aspect quotient based on supplied view and * content dimensions. * * @param viewwidth * Width of view * @param viewheight * * Height of view * @param contentwidth * Width of content * @param contentheight * Height of content/public void updateaspectquotient (float VIEWWI DTH, float viewheight, float contentwidth, float contentheight) {final float aspectquotient = (contentwidth/cont
Entheight)/(Viewwidth/viewheight);
if (aspectquotient!= maspectquotient) {maspectquotient = aspectquotient;
Setchanged (); }} private class Zoomstate extends observable {/** * Zoom level A value of 1.0 means the content fits the VI
ew.
* * Private float mzoom;
/** * Pan position x-coordinate x-coordinate of Zoom window Center * position, relative to the width of the content.
* * Private float Mpanx;
/** * Pan position y-coordinate y-coordinate of Zoom window Center* position, relative to the "the" content.
* * Private float Mpany; Public methods/** * Get current X-pan * * @return current X-pan/public float Getpanx () {retur
n Mpanx;
/** * Get Current Y-pan * * @return current Y-pan/public float Getpany () {return mpany; /** * Get Current ZOOM value * * @return Current ZOOM value */public float getzoom () {return Mzoo
M /** * Help function for calculating current zoom value in x-dimension * * @param aspectquotient * (Asp ECT ratio content)/(Aspect ratio view) * @return Current zoom value into x-dimension/public float GETZOOMX (Floa
T aspectquotient) {return math.min (mzoom, Mzoom * aspectquotient); /** * Help function for calculating current zoom value in y-dimension * * @param aspectquotient * (Asp ECT ratio content)/(Aspect ratio view) * @return Current zoom value in Y-dimension/publiC Float getzoomy (float aspectquotient) {return math.min (Mzoom, mzoom/aspectquotient); /** * Set pan-x * * @param panx * pan-x value to Set */public void Setpanx (float Panx) {if (
Panx!= mpanx) {Mpanx = Panx;
Setchanged ();
}/** * Set pan-y * * @param pany * pan-y value to set */public void Setpany (float pany) {
if (pany!= mpany) {mpany = pany;
Setchanged (); }/** * Set zoom * * @param zoom * Zoom value to set */public void setzoom (float zoom) {if (Zoom!= Mzoom)
{mzoom = zoom;
Setchanged ();
}
}
}
}
3. Project main file Mainactivity.java code:
Package com.ymw.zoomimage;
Import android.app.Activity;
Import Android.graphics.Bitmap;
Import android.graphics.BitmapFactory;
Import Android.os.Bundle;
public class Mainactivity extends activity {
private zoomimageview zoomimg;
@Override public
void OnCreate (Bundle savedinstancestate) {
super.oncreate (savedinstancestate);
Setcontentview (r.layout.main);
Zoomimg = (Zoomimageview) Findviewbyid (r.id.image);
Bitmap Bitmap = Bitmapfactory.decoderesource (This.getresources (),
r.drawable.a);
Zoomimg.setimage (bitmap);
}
This is the Android multi-touch zoom to reduce the image of the sample code, I hope to help you learn.