Version: 1.0Date: 2014.8.4Copyright: © kince Reproduced in the source
before reading an article, the link is: You can pull down to zoom Headerview Listview:pulltozoominlistview. That's pulltozoomlistview, but there's a place in this article that needs an erratum, which is Pulltozoomlistview, although it's a source project on GitHub. But the most beautiful application is not to use this open source project, but the open source project to decompile the most beautiful application code. However, this code is problematic, and the Onitemclick event is raised when the finger slides on the screen. Looking at its code, it was found that the return to true in Motionevent.action_move in the Ontouchevent () method would consume this event, resulting in onitemclick event. Then I also decompile the most beautiful application, looked at the implementation of this control, found that there are other problems, such as the lack of some variables, not rewrite the Onintercepttouchevent () method, etc., so I do it myself to enrich the control, so that it can be as close as possible to the original code , and can be used normally. The following code is modified:
Package Com.kince.android.pulltozoomlistview;import Android.app.activity;import Android.content.context;import Android.os.systemclock;import Android.util.attributeset;import Android.util.displaymetrics;import Android.util.log;import Android.view.motionevent;import Android.view.viewgroup;import Android.view.animation.interpolator;import Android.widget.abslistview;import Android.widget.FrameLayout;import Android.widget.imageview;import Android.widget.listview;public class Pulltozoomlistview extends ListView Implementsabslistview.onscrolllistener {private static final int invalid_value = -1;private static final String TAG = "Pul Ltozoomlistview ";p rivate static final interpolator sinterpolator = new Interpolator () {public float getinterpolation ( Float paramanonymousfloat) {float F = Paramanonymousfloat-1.0f;return 1.0F + f * (f * (f * (f * f)));}; int mactivepointerid = -1;private framelayout mheadercontainer;private int mheaderheight;private ImageView mHeaderImage ; Float Mlastmotiony =-1.0f;float Mlastscale = -1.0f;float Mmaxscale = -1.0f;private Abslistview.onscrolllistener mOnScrollListener;private scalingrunnalable mscalingrunnalable;private int Mscreenheight;private ImageView mshadow;private Boolean mScrollable = True;private Boolean mshowheaderimage = true;private Boolean mzoomable = True;public Pulltozoomlistview (Context Paramcontext) {super (Paramcontext); init (paramcontext);} Public Pulltozoomlistview (Context Paramcontext,attributeset paramattributeset) {super (Paramcontext, Paramattributeset); init (paramcontext);} Public Pulltozoomlistview (Context paramcontext,attributeset paramattributeset, int paramint) {super (Paramcontext, Paramattributeset, Paramint); init (paramcontext);} private void endscraling () {if (This.mHeaderContainer.getBottom () >= this.mheaderheight) log.d ("Mmm", "endscraling" ); This.mScalingRunnalable.startAnimation (200L);} private void init (Context paramcontext) {displaymetrics localdisplaymetrics = new Displaymetrics ();((Activity) Paramcontext). GetwindOwmanager (). Getdefaultdisplay (). Getmetrics (localdisplaymetrics); this.mscreenheight = Localdisplaymetrics.heightpixels;this.mheadercontainer = new Framelayout (paramcontext); this.mHeaderImage = new ImageView (paramcontext); int i = Localdisplaymetrics.widthpixels;setheaderviewsize (i, (int) (9.0F * (i/16.0f))); This.mshadow = new ImageView (paramcontext); Framelayout.layoutparams locallayoutparams = new Framelayout.layoutparams ( -1,-2); locallayoutparams.gravity = 80; This.mShadow.setLayoutParams (Locallayoutparams); This.mHeaderContainer.addView (this.mheaderimage); This.mHeaderContainer.addView (This.mshadow); Addheaderview (this.mheadercontainer); this.mscalingrunnalable = new Scalingrunnalable (); Super.setonscrolllistener (this);} private void Onsecondarypointerup (Motionevent parammotionevent) {int i = (parammotionevent.getaction ()) >> 8; LOG.D ("Onsecondarypointerup", I + ""); if (Parammotionevent.getpointerid (i) = = This.mactivepointerid) if (i! = 0) { This.mlastmotiony = parammotionevent.gety (1); tHis.mactivepointerid = Parammotionevent.getpointerid (0); return;}} private void Reset () {This.mactivepointerid = -1;this.mlastmotiony = -1.0f;this.mmaxscale = -1.0f;this.mlastscale = -1.0F ;} Public ImageView Getheaderview () {return this.mheaderimage;} public void Hideheaderimage () {this.mshowheaderimage = False;this.mzoomable = False;this.mscrollable = false; Removeheaderview (This.mheadercontainer);} public Boolean isscrollable () {return this.mscrollable;} public Boolean iszoomable () {return this.mzoomable;} public boolean onintercepttouchevent (Motionevent parammotionevent) {if (!this.mzoomable) {return Super.onintercepttouchevent (parammotionevent);} Switch (parammotionevent.getaction () & Motionevent.action_mask) {case Motionevent.action_down: This.mactivepointerid = Parammotionevent.getpointerid (0); This.mmaxscale = (this.mscreenheight/this.mheaderheight); Break;case MotionEvent.ACTION_UP:reset (); Break;case MotionEvent.ACTION_POINTER_DOWN:this.mActivePointerId = Parammotionevent.getpointeriD (Parammotionevent.getactionindex ()); Break;case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp ( Parammotionevent); break;} Return super.onintercepttouchevent (parammotionevent);} protected void OnLayout (Boolean paramboolean, int paramInt1, int paramint2,int paramInt3, int paramInt4) {super.onlayout ( Paramboolean, ParamInt1, ParamInt2, ParamInt3, paramInt4); if (this.mheaderheight = = 0) This.mheaderheight = This.mHeaderContainer.getHeight ();} @Overridepublic void Onscroll (Abslistview paramabslistview, int paramint1,int paramInt2, int paramInt3) {if ( this.mscrollable) {log.d (TAG, "onscroll"); float f = this.mheaderheight-this.mheadercontainer.getbottom (); LOG.D ("Onscroll", "f|" + f), if ((F > 0.0F) && (F < this.mheaderheight)) {log.d ("Onscroll", "1"); int i = (int ) (0.65D * f); This.mHeaderImage.scrollTo (0,-i);} else if (This.mHeaderImage.getScrollY ()! = 0) {log.d ("Onscroll", "2"); This.mHeaderImage.scrollTo (0, 0);}} if (This.monscrolllistener! = null) {This.mOnScrollListener.onScroLL (Paramabslistview, Paramint1,paramint2, ParamInt3);}} public void onscrollstatechanged (Abslistview paramabslistview, int paramint) {if (This.monscrolllistener! = null) This.mOnScrollListener.onScrollStateChanged (paramabslistview,paramint);} public boolean ontouchevent (motionevent ev) {LOG.D (TAG, "" + (0xFF & Ev.getaction ())), if (!this.mzoomable) {log.i ("Zo Om "," Zoom "); return super.ontouchevent (EV);} Switch (ev.getaction () & Motionevent.action_mask) {case MotionEvent.ACTION_OUTSIDE:case Motionevent.action_down: if (!this.mscalingrunnalable.misfinished) {this.mScalingRunnalable.abortAnimation ();} This.mlastmotiony = Ev.gety (); this.mactivepointerid = Ev.getpointerid (0); This.mmaxscale = (This.mscreenheight/ This.mheaderheight); This.mlastscale = (This.mHeaderContainer.getBottom ()/this.mheaderheight); break;case MOTIONEVENT.ACTION_MOVE:LOG.D ("Ontouchevent", "Mactivepointerid" + mactivepointerid); int J = Ev.findpointerindex ( This.mactivepointerid); if (j = =-1) {LOG.E ("Pulltozoomlistview"), "Invalid pointerid=" + This.mactivepointerid + "in Ontouchevent");} else {if (This.mlastmotiony = = -1.0f) This.mlastmotiony = Ev.gety (j); if (This.mHeaderContainer.getBottom () >= This.mheaderheight) {Viewgroup.layoutparams locallayoutparams = This.mHeaderContainer.getLayoutParams (); float F = (( Ev.gety (j)-This.mlastmotiony + this.mHeaderContainer.getBottom ())/This.mheaderheight-this.mlastscale)/2.0F + this. Mlastscale;if ((This.mlastscale <= 1.0D) && (F < This.mlastscale)) {locallayoutparams.height = This.mheaderheight;this.mheadercontainer.setlayoutparams (locallayoutparams);} This.mlastscale = Math.min (Math.max (f, 1.0F), this.mmaxscale); locallayoutparams.height = ((int) (This.mheaderheight * This.mlastscale)); if (Locallayoutparams.height < this.mscreenheight) This.mHeaderContainer.setLayoutParams ( Locallayoutparams); this.mlastmotiony = Ev.gety (j);} This.mlastmotiony = Ev.gety (j);} Break;case MotionEvent.ACTION_UP:reset (); endscraling (); Break;case Motionevent.action_cAncel:break;case MotionEvent.ACTION_POINTER_DOWN:int i = Ev.getactionindex (); this.mlastmotiony = Ev.gety (i); This.mactivepointerid = Ev.getpointerid (i); break;case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp (EV); This.mlastmotiony = Ev.gety (Ev.findpointerindex (This.mactivepointerid)); return super.ontouchevent (EV);} public void setheaderviewsize (int paramInt1, int paramInt2) {if (!this.mshowheaderimage) {return;} Object localobject = This.mHeaderContainer.getLayoutParams (); if (localobject = = null) Localobject = new Abslistview.layoutparams (ParamInt1, ParamInt2);((viewgroup.layoutparams) localobject). width = paramInt1; (( Viewgroup.layoutparams) localobject). Height = Paramint2;this.mheadercontainer.setlayoutparams (( Viewgroup.layoutparams) localobject); this.mheaderheight = ParamInt2;} public void Setonscrolllistener (Abslistview.onscrolllistener paramonscrolllistener) {This.monscrolllistener = Paramonscrolllistener;} public void Setscrollable (Boolean Paramboolean) {if (!this.mshowheadeRImage) {return;} this.mscrollable = Paramboolean;} public void Setshadow (int paramint) {if (!this.mshowheaderimage) {return;} This.mShadow.setBackgroundResource (paramint);} public void Setzoomable (Boolean Paramboolean) {if (!this.mshowheaderimage) {return;} this.mzoomable = Paramboolean;} Class Scalingrunnalable implements Runnable {long Mduration;boolean misfinished = True;float Mscale;long mstarttime; Scalingrunnalable () {}public void abortanimation () {this.misfinished = true;} public Boolean isfinished () {return this.misfinished;} public void Run () {float F2; Viewgroup.layoutparams locallayoutparams;if ((!this.misfinished) && (This.mscale > 1.0D)) {Float F1 = ((float ) Systemclock.currentthreadtimemillis ()-(float) this.mstarttime)/(float) This.mduration;f2 = This.mscale-( this.mscale-1.0f) * PullToZoomListView.sInterpolator.getInterpolation (f1); locallayoutparams = PullToZoomListView.this.mHeaderContainer.getLayoutParams (), if (F2 > 1.0F) {log.d ("Mmm", "f2>1.0"); locallayouTparams.height = Pulltozoomlistview.this.mheaderheight;locallayoutparams.height = ((int) (F2 * PullToZoomListView.this.mHeaderHeight)); PullToZoomListView.this.mHeaderContainer.setLayoutParams (Locallayoutparams); PullToZoomListView.this.post (this); return;} This.misfinished = True;}} public void Startanimation (long paramlong) {this.mstarttime = Systemclock.currentthreadtimemillis (); this.mduration = Paramlong;this.mscale = ((float) (PullToZoomListView.this.mHeaderContainer.getBottom ())/ PullToZoomListView.this.mHeaderHeight); this.misfinished = false; PullToZoomListView.this.post (this);}}}About the implementation of this control principle can refer to the above linked articles, which have a more detailed explanation, here no longer repeat. The effect is the following: GitHub link: https://github.com/wangjinyu501/PullToZoomListView/, if you find any problems, you can leave a message under the article, I will be the first time to deal with, welcome to exchange.