Homepage 3 -- rebound of pull-down on the interface; 3 -- pull-down
Public class MyScrollView extends ScrollView {private View childView; public MyScrollView (Context context) {super (context);} public MyScrollView (Context context, AttributeSet attrs) {super (context, attrs);} public MyScrollView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr);} // @ Override // protected void onLayout (boolean changed, int l, int t, int R, int B) {// super. onLayout (changed, l, t, r, B); // obtain the subview @ Override protected void onFinishInflate () {super. onFinishInflate (); if (getChildCount ()> 0) {childView = getChildAt (0) ;}} private int lastY; // The Coordinate Position of the last Y-axis operation, private Rect normal = new Rect (); // private boolean isFinishAnimation = true, used to record the critical state; // whether the animation ends. private int lastX, downX, and downY; // interception: whether the parent view blocks the child views. // whether the interception succeeds depends on the return value of the method. Return Value true: the interception is successful. Otherwise, the interception fails @ Override public boolean onInterceptTouchEvent (MotionEvent ev) {boolean isIntercept = false; int eventX = (int) ev. getX (); int eventY = (int) ev. getY (); switch (ev. getAction () {case MotionEvent. ACTION_DOWN: lastX = downX = eventX; lastY = downY = eventY; break; case MotionEvent. ACTION_MOVE: // obtain the moving distance between the horizontal and vertical directions. int absX = Math. abs (eventX-downX); int absY = Math. abs (eventY-downY); if (absY> AbsX & absY> = UIUtils. dp2px (10) {isIntercept = true; // execution interception} lastX = eventX; lastY = eventY; break;} return isIntercept;} @ Override public boolean onTouchEvent (MotionEvent ev) {if (childView = null |! IsFinishAnimation) {return super. onTouchEvent (ev);} int eventY = (int) ev. getY (); // obtain the current Y axis switch (ev. getAction () {case MotionEvent. ACTION_DOWN: lastY = eventY; break; case MotionEvent. ACTION_MOVE: int dy = eventY-lastY; // tiny movement if (isNeedMove () {if (normal. isEmpty () {// records the left, top, right, and bottom normal critical states of childView. set (childView. getLeft (), childView. getTop (), childView. getRight (), childView. getBotto M ();} // re-layout childView. layout (childView. getLeft (), childView. getTop () + dy/2, childView. getRight (), childView. getBottom () + dy/2);} lastY = eventY; // revalue break; case MotionEvent. ACTION_UP: if (isNeedAnimation () {// use the translation animation int translateY = childView. getBottom ()-normal. bottom; TranslateAnimation translateAnimation = new TranslateAnimation (0, 0, 0,-translateY); translateAnimation. setDurati On (200); // translateAnimation. setFillAfter (true); // stay at the final position. setAnimationListener (new Animation. animationListener () {@ Override public void onAnimationStart (Animation animation) {isFinishAnimation = false;} @ Override public void onAnimationEnd (Animation animation) {region = true; childView. clearAnimation (); // clear the animation // relay the childView. layout (normal. left, normal. top, norm Al. right, normal. bottom); // clear normal data normal. setEmpty () ;}@ Override public void onAnimationRepeat (Animation animation) {}}); // start the Animation childView. startAnimation (translateAnimation);} break;} return super. onTouchEvent (ev) ;}// determine whether to execute the pan animation private boolean isNeedAnimation () {return! Normal. isEmpty ();} private boolean isNeedMove () {int childMeasuredHeight = childView. getMeasuredHeight (); // get the height of the subview int scrollViewMeasuredHeight = this. getMeasuredHeight (); // obtain the layout height Log. e ("TAG", "childMeasuredHeight =" + childMeasuredHeight); Log. e ("TAG", "scrollViewMeasuredHeight =" + scrollViewMeasuredHeight); int dy = childMeasuredHeight-scrollViewMeasuredHeight; // dy> = 0 int scrollY = thi S. getScrollY (); // get the offset (upper + lower-) if (scrollY <= 0 | scrollY> = dy) {return true; // process according to the custom MyScrollView method} // if other values are in the critical range, false is returned. That is, return false is still processed in ScrollView mode ;}}