Viewpager Picture preview Image Zoom out, move, toggle (fourth lesson) it's over.

Source: Internet
Author: User
Tags gety


Ultimate Edition

Package Com.zhy.view;import Android.annotation.suppresslint;import Android.content.context;import Android.graphics.matrix;import Android.graphics.rectf;import Android.graphics.drawable.drawable;import Android.util.attributeset;import Android.util.log;import Android.view.gesturedetector;import Android.view.motionevent;import Android.view.scalegesturedetector;import Android.view.gesturedetector.simpleongesturelistener;import Android.view.scalegesturedetector.onscalegesturelistener;import Android.view.view;import Android.view.view.ontouchlistener;import Android.view.viewtreeobserver;import android.widget.ImageView;/** * * @ Author Zhy * Blog address: http://blog.csdn.net/lmj623565791 */public class Zoomimageview extends ImageView implements Onscalegesturelistener,ontouchlistener, viewtreeobserver.ongloballayoutlistener{private static final String TAG = ZoomImageView.class.getSimpleName ();p ublic static final float Scale_max = 4.0f;private static final float Scale_mid = 2.0f /** * When initializing the zoom ratio, if the picture is wide or tallOn the screen, this value will be less than 0 */private float Initscale = 1.0f;private Boolean once = true;/** * For storing 9 values of the Matrix */private final float[] Matrixval ues = new float[9];/** * Zoom gesture detection */private scalegesturedetector mscalegesturedetector = null;private final Matrix mscalema Trix = new Matrix ();/** * for double-click Detection */private gesturedetector mgesturedetector;private boolean isautoscale;private int MTouch slop;private Float mlastx;private float mlasty;private boolean iscandrag;private int Lastpointercount;private Boolean Ischecktopandbottom = true;private Boolean ischeckleftandright = True;public Zoomimageview (context context) {This ( context, NULL);} Public Zoomimageview (context context, AttributeSet Attrs) {Super (context, attrs); Super.setscaletype (Scaletype.matrix ); mgesturedetector = new Gesturedetector (context,new Simpleongesturelistener () {@Overridepublic Boolean Ondoubletap ( Motionevent e) {if (Isautoscale = = true) return true;float x = E.getx (); Float y = e.gety (); LOG.E ("Doubletap", Getscale () + "," + Initscale); if (Getscale () &LT Scale_mid) {ZoomImageView.this.postDelayed (new autoscalerunnable (Scale_mid, x, y), +); Isautoscale = true;} else if ( Getscale () >= scale_mid&& Getscale () < Scale_max) {ZoomImageView.this.postDelayed (new autoscalerunnable (Scale_max, x, y), +); Isautoscale = true;} Else{zoomimageview.this.postdelayed (New Autoscalerunnable (Initscale, x, y), +); Isautoscale = true;} return true;}}); Mscalegesturedetector = new Scalegesturedetector (context, this); This.setontouchlistener (this);} /** * Auto-scaling Tasks * * @author Zhy * */private class Autoscalerunnable implements runnable{static final float bigger = 1.07f;  Static final float SMALLER = 0.93f;private float mtargetscale;private float tmpscale;/** * Zoom Center */private float X;private  FLOAT y;/** * Incoming target zoom value, according to the target value and the current value, determine whether to enlarge or reduce the * @param targetscale */public autoscalerunnable (float targetscale, float x, Float y) {This.mtargetscale = Targetscale;this.x = X;this.y = Y;if (Getscale () < Mtargetscale) {Tmpscale = BIGGER;} else {Tmpscale = SMALLER;}}@Overridepublic void Run () {//scaled Mscalematrix.postscale (Tmpscale, Tmpscale, x, y); Checkborderandcenterwhenscale (); Setimagematrix (Mscalematrix); final float Currentscale = Getscale ();//If the value is within the legal range, continue scaling if ((Tmpscale > 1f) && ( Currentscale < Mtargetscale) | | ((Tmpscale < 1f) && (Mtargetscale < Currentscale))) {ZoomImageView.this.postDelayed (this, 16);} else//set to the target scale {final float Deltascale = Mtargetscale/currentscale;mscalematrix.postscale (Deltascale, Deltascale, X , y); Checkborderandcenterwhenscale (); Setimagematrix (Mscalematrix); isautoscale = false;}}} @SuppressLint ("Newapi") @Overridepublic boolean Onscale (Scalegesturedetector detector) {Float scale = Getscale (); float Scalefactor = Detector.getscalefactor (); if (getdrawable () = = NULL) return true;/** * Zoom range Control */if (Scale < Scale_max &A mp;& scalefactor > 1.0f) | | (Scale > Initscale && scalefactor < 1.0f)) {/** * Maximum minimum value */if (scalefactor * Scale < Initscale) {scalefactor = Initscale/scale;} if (Scalefactor * scale > Scale_max) {scalefactor = Scale_max/scale;} /** * Set Scaling */mscalematrix.postscale (Scalefactor, Scalefactor,detector.getfocusx (), detector.getfocusy ()); Checkborderandcenterwhenscale (); Setimagematrix (Mscalematrix);} return true;} /** * When zooming, the control of the picture display range */private void Checkborderandcenterwhenscale () {RECTF rect = GETMATRIXRECTF (); Float deltax = 0;floa  T DeltaY = 0;int width = getwidth (); int height = getheight ();//If the width or height is greater than the screen, then the control range if (Rect.width () >= width) {if (rect.left > 0) {deltax =-rect.left;} if (Rect.right < width) {deltax = Width-rect.right;}} if (rect.height () >= height) {if (Rect.top > 0) {deltay =-rect.top;} if (Rect.bottom < height) {deltay = Height-rect.bottom;}} If the width or height is less than the screen, let it be centered if (Rect.width () < width) {deltax = width * 0.5f-rect.right + 0.5f * rect.width ();} if (Rect.height () < height) {deltay = height * 0.5f-rect.bottom + 0.5f * rect.height ();} LOG.E (TAG, "deltax =" + DeltaX + ", DeltaY =" + DeltaY); Mscalematrix.posttRanslate (DeltaX, DeltaY);} /** * Gets the range of images according to the matrix of the current picture * * @return */private RECTF GETMATRIXRECTF () {Matrix Matrix = Mscalematrix; RECTF rect = new RECTF ();D rawable d = getdrawable (), if (null! = d) {rect.set (0, 0, d.getintrinsicwidth (), D.getintrinsichei Ght ()); Matrix.maprect (rect);} return rect; @Overridepublic Boolean onscalebegin (Scalegesturedetector detector) {return true;} @Overridepublic void Onscaleend (Scalegesturedetector detector) {} @Overridepublic boolean OnTouch (View V, motionevent Event) {if (Mgesturedetector.ontouchevent (event)) return True;mscalegesturedetector.ontouchevent (event); float x = 0, y = 0;//Gets the number of touch points final int pointercount = Event.getpointercount ();//Gets the X and y mean values for multiple touch points for (int i = 0; i < Pointercount; i++) { x + = Event.getx (i); y + = event.gety (i); x = X/pointercount;y = y/pointercount;/** * Resets mlasx, mlasty */if (pointercount! = lastpointercount) Whenever the touch point changes, IsCanD Rag = False;mlastx = X;mlasty = y;} Lastpointercount = Pointercount; RECTF RECTF = GETMATRIXRECTF (); switch (event. Getaction ()) {Case MotionEvent.ACTION_DOWN:if (rectf.width () > getwidth () | | rectf.height () > GetHeight ()) { GetParent (). Requestdisallowintercepttouchevent (True); Break;case MotionEvent.ACTION_MOVE:if (Rectf.width () > getwidth () | | rectf.height () > GetHeight ()) {getParent (). Requestdisallowintercepttouchevent (TRUE);} LOG.E (TAG, "action_move"); float dx = x-mlastx;float dy = y-mlasty;if (!iscandrag) {Iscandrag = Iscandrag (dx, dy);} if (Iscandrag) {if (getdrawable () = null) {//if (GETMATRIXRECTF (). left = = 0 && dx > 0)//{//GetParent (). reques Tdisallowintercepttouchevent (false);//}////if (GETMATRIXRECTF (). Right = = getwidth () && DX < 0)//{//Getpare NT (). Requestdisallowintercepttouchevent (false);//}ischeckleftandright = Ischecktopandbottom = true;//If the width is less than the screen width, Then disable left and right moves if (Rectf.width () < GetWidth ()) {dx = 0;ischeckleftandright = false;} If the height of the screen is highly cloudy, it is forbidden to move up or down if (Rectf.height () < GetHeight ()) {dy = 0;ischecktopandbottom = false;} Mscalematrix.posttranslate (dx, dy); Checkmatrixbounds (); Setimagematrix (Mscalematrix);}} MLASTX = X;mlasty = Y;break;case MotionEvent.ACTION_UP:case motionevent.action_cancel:log.e (TAG, "action_up"); Lastpointercount = 0;break;} return true;} /** * Get Current ZOOM ratio * * @return */public final float Getscale () {mscalematrix.getvalues (matrixvalues); return Matrixvalues[mat Rix. MSCALE_X];} @Overrideprotected void Onattachedtowindow () {Super.onattachedtowindow (); Getviewtreeobserver (). Addongloballayoutlistener (this);} @SuppressWarnings ("deprecation") @Overrideprotected void Ondetachedfromwindow () {Super.ondetachedfromwindow (); Getviewtreeobserver (). Removeglobalonlayoutlistener (this);} @Overridepublic void Ongloballayout () {if (once) {drawable d = getdrawable (); if (d = = null) return; LOG.E (TAG, d.getintrinsicwidth () + "," + d.getintrinsicheight ()); int width = getwidth (); int height = getheight ();//Get Picture The width and height of the int dw = D.getintrinsicwidth (); int dh = d.getintrinsicheight (); float scale = 1.0f;//If the picture is wide or tall on the screen, zoom to the width or height of the screen if (DW & Gt Width && DH <= height) {scale = width * 1.0F/DW;} if (DH > Height && DW <= width) {scale = height * 1.0F/DH;} If the width and height are larger than the screen, let it fit the screen size proportionally if (DW > Width && dh > height) {scale = Math.min (width * 1.0f/dw, Height * 1.0f /DH);} Initscale = scale; LOG.E (TAG, "Initscale =" + Initscale); Mscalematrix.posttranslate ((WIDTH-DW)/2, (HEIGHT-DH)/2); MSCALEMATRIX.POSTSC Ale (scale, scale, getwidth ()/2,getheight ()/2),//Picture moved to Screen center Setimagematrix (mscalematrix); once = false;}} /** * When moving, the boundary is judged, the main judgment is that the width or height is greater than the screen */private void Checkmatrixbounds () {RECTF rect = GETMATRIXRECTF (); float deltax = 0, DeltaY = 0;final float viewwidth = getwidth (); final float viewheight = getheight ();//Determines whether the picture is displayed beyond the screen boundary if it is moved or scaled if (Rect.top > 0 &amp ;& ischecktopandbottom) {deltay =-rect.top;} if (Rect.bottom < viewheight && ischecktopandbottom) {deltay = Viewheight-rect.bottom;} if (Rect.left > 0 && ischeckleftandright) {deltax =-rect.left;} if (Rect.right < Viewwidth && isCheckleftandright) {deltax = Viewwidth-rect.right;} Mscalematrix.posttranslate (DeltaX, DeltaY);} /** * is the push behavior * * @param dx * @param dy * @return */private boolean iscandrag (float dx, float dy) {return math.sqrt (DX * DX) + (dy * dy)) >= mtouchslop;}}


Layout file: Activity_main.xml

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:tools= "http// Schemas.android.com/tools "    android:layout_width=" match_parent "    android:layout_height=" Match_parent " >    <com.zhy.view.zoomimageview        android:layout_width= "fill_parent"        android:layout_height= "fill _parent "        android:scaletype=" Matrix "        android:src=" @drawable/tbug "/></relativelayout>

Vp.xml

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:tools= "http// Schemas.android.com/tools "    android:layout_width=" match_parent "    android:layout_height=" Match_parent " >    <android.support.v4.view.viewpager        android:id= "@+id/id_viewpager"        android:layout_width= " Fill_parent "        android:layout_height=" fill_parent ">    </android.support.v4.view.viewpager></ Relativelayout>


Use in activity:

Package Com.zhy.zhy_scalegesturedetector02;import Android.app.activity;import Android.os.bundle;import Android.support.v4.view.pageradapter;import Android.support.v4.view.viewpager;import Android.view.View;import Android.view.viewgroup;import Android.widget.imageview;import Com.zhy.view.zoomimageview;public class MainActivity Extends Activity{private viewpager mviewpager;private int[] Mimgs = new int[] {r.drawable.tbug, r.drawable.a,r.drawable. XX};p rivate imageview[] mimageviews = new Imageview[mimgs.length]; @Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.LAYOUT.VP); MViewPager = (ViewPager) Findviewbyid (R.id.id_viewpager); Mviewpager.setadapter (new Pageradapter () {@Overridepublic Object Instantiateitem ( ViewGroup container, int position) {Zoomimageview ImageView = new Zoomimageview (Getapplicationcontext ()); Imageview.setimageresource (Mimgs[position]); Container.addview (ImageView); mimageviews[position] = ImageView; Return ImagevIew;} @Overridepublic void Destroyitem (ViewGroup container, int position,object Object) {Container.removeview (mimageviews[ Position]);} @Overridepublic boolean isviewfromobject (View arg0, Object arg1) {return arg0 = = arg1;} @Overridepublic int GetCount () {return mimgs.length;}});}}


Viewpager Picture preview Image Zoom out, move, toggle (fourth lesson) it's over.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.