Package Com.itau.jingdong.widgets;import Android.content.context;import android.graphics.rect;import Android.util.attributeset;import Android.view.motionevent;import Android.view.view;import Android.view.animation.translateanimation;import Android.widget.ScrollView;/** @description ScrollView with rebound effect, can be compatible with horizontal sliding*/ Public classAbscrollview extends ScrollView {PrivateView inner;//Kids View Private StaticFinalintDefault_position =-1; Private floaty = default_position;//coordinates of y when clicked PrivateRect normal =NewRect (); //sliding distance and coordinates Private floatxdistance, Ydistance, XLAST, Ylast; PublicAbscrollview (Context context, AttributeSet Attrs) {Super (context, attrs); } /** * Based on the XML generation View work done, the function in the final call to generate the view, after all the child views are added, even if the subclass overrides the Onfinishinflate * method, you should call the method of the parent class, so that the method can be executed*/@Overrideprotected voidonfinishinflate () {if(Getchildcount () >0) {Inner= Getchildat (0); }} @Override Publicboolean ontouchevent (motionevent ev) {if(Inner = =NULL) { returnsuper.ontouchevent (EV); } Else{commontouchevent (EV); } returnsuper.ontouchevent (EV); } Public voidcommontouchevent (motionevent ev) {intAction =ev.getaction (); Switch(action) { Casemotionevent.action_down:y=ev.gety (); Break; Casemotionevent.action_up:if(Isneedanimation ()) {animation (); } y=default_position; Break; /** excluding the first move calculation, because the first time I was unable to know the left of Y, not get in Motionevent.action_down, * because this is Myscrollview tocuh time passed to the child of the ListView it EM above. So from the second start calculation * However, we also want to initialize, that is, the first time to move the sliding distance to zero, then the record is accurate and normal execution*/ CaseMotionevent.action_move:floatPreY =y; floatNowy =ev.gety (); if(Isdefaultposition (y)) {PreY=Nowy; } intDeltaY = (int) (PreY-Nowy); Scrollby (0, DeltaY); Y=Nowy; //when scrolling to the top or bottom, no more scrolling, then move the layout if(Isneedmove ()) {if(Normal.isempty ()) {//save a normal layout locationNormal.Set(Inner.getleft (), Inner.gettop (), Inner.getright (), Inner.getbottom ()); } //Mobile LayoutsInner.layout (Inner.getleft (), Inner.gettop ()-DeltaY, Inner.getright (), Inner.getbottom ()-DeltaY); } Break; default: Break; } } //Turn on animation movement Public voidAnimation () {//turn on mobile animationTranslateanimation TA =NewTranslateanimation (0,0, Inner.gettop (), normal.top); Ta.setduration ( $); Inner.startanimation (TA); //set back to normal layout positioninner.layout (Normal.left, Normal.top, Normal.right, Normal.bottom); Normal.setempty (); } //do you want to turn on animation PublicBoolean isneedanimation () {return!Normal.isempty (); } //Whether you need to move the layout PublicBoolean isneedmove () {intoffset = inner.getmeasuredheight ()-getheight (); intscrolly =getscrolly (); if(scrolly = =0|| scrolly = =offset) { return true; } return false; } //Check if it is in the default location PrivateBoolean isdefaultposition (floatposition) { returnPosition = =default_position; } @Override Publicboolean onintercepttouchevent (motionevent ev) {Switch(Ev.getaction ()) { CaseMotionEvent.ACTION_DOWN:xDistance= Ydistance =0f; XLAST=Ev.getx (); Ylast=ev.gety (); Break; CaseMotionEvent.ACTION_MOVE:finalfloatCurX =Ev.getx (); FinalfloatCurY =ev.gety (); Xdistance+ = Math.Abs (CurX-XLAST); Ydistance+ = Math.Abs (CurY-ylast); XLAST=CurX; Ylast=CurY; if(Xdistance >ydistance) { return false; } } returnsuper.onintercepttouchevent (EV); }}
Android Custom ScrollView (ScrollView with rebound effect, can be compatible with horizontal sliding)