Android--实现ViewPager边界回弹效果(转)

该View转自   http://blog.csdn.net/Kalwang/article/details/4708721  ,感谢这位大神。

  1 public class BounceBackViewPager extends ViewPager {
  2 
  3     private int currentPosition = 0;
  4     private Rect mRect = new Rect();//用来记录初始位置
  5     private boolean handleDefault = true;
  6     private float preX = 0f;
  7     private static final float RATIO = 0.5f;//摩擦系数
  8     private static final float SCROLL_WIDTH = 10f;
  9 
 10     public BounceBackViewPager(Context context) {
 11         super(context);
 12     }
 13 
 14     public BounceBackViewPager(Context context, AttributeSet attrs) {
 15         super(context, attrs);
 16     }
 17 
 18     @Override
 19     public boolean dispatchKeyEvent(KeyEvent event) {
 20         return super.dispatchKeyEvent(event);
 21     }
 22 
 23     @Override
 24     public boolean onInterceptTouchEvent(MotionEvent ev) {
 25         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
 26             preX = ev.getX();//记录起点
 27             currentPosition = getCurrentItem();
 28         }
 29         return super.onInterceptTouchEvent(ev);
 30     }
 31 
 32     @Override
 33     public boolean onTouchEvent(MotionEvent ev) {
 34         switch (ev.getAction()) {
 35             case MotionEvent.ACTION_UP:
 36                 onTouchActionUp();
 37                 break;
 38             case MotionEvent.ACTION_MOVE:
 39                 if (getAdapter().getCount() == 1) {
 40                     float nowX = ev.getX();
 41                     float offset = nowX - preX;
 42                     preX = nowX;
 43 
 44                     if (offset > SCROLL_WIDTH) {//手指滑动的距离大于设定值
 45                         whetherConditionIsRight(offset);
 46                     } else if (offset < -SCROLL_WIDTH) {
 47                         whetherConditionIsRight(offset);
 48                     } else if (!handleDefault) {//这种情况是已经出现缓冲区域了,手指慢慢恢复的情况
 49                         if (getLeft() + (int) (offset * RATIO) != mRect.left) {
 50                             layout(getLeft() + (int) (offset * RATIO), getTop(), getRight() + (int) (offset * RATIO), getBottom());
 51                         }
 52                     }
 53                 } else if ((currentPosition == 0 || currentPosition == getAdapter().getCount() - 1)) {
 54                     float nowX = ev.getX();
 55                     float offset = nowX - preX;
 56                     preX = nowX;
 57 
 58                     if (currentPosition == 0) {
 59                         if (offset > SCROLL_WIDTH) {//手指滑动的距离大于设定值
 60                             whetherConditionIsRight(offset);
 61                         } else if (!handleDefault) {//这种情况是已经出现缓冲区域了,手指慢慢恢复的情况
 62                             if (getLeft() + (int) (offset * RATIO) >= mRect.left) {
 63                                 layout(getLeft() + (int) (offset * RATIO), getTop(), getRight() + (int) (offset * RATIO), getBottom());
 64                             }
 65                         }
 66                     } else {
 67                         if (offset < -SCROLL_WIDTH) {
 68                             whetherConditionIsRight(offset);
 69                         } else if (!handleDefault) {
 70                             if (getRight() + (int) (offset * RATIO) <= mRect.right) {
 71                                 layout(getLeft() + (int) (offset * RATIO), getTop(), getRight() + (int) (offset * RATIO), getBottom());
 72                             }
 73                         }
 74                     }
 75                 } else {
 76                     handleDefault = true;
 77                 }
 78 
 79                 if (!handleDefault) {
 80                     return true;
 81                 }
 82                 break;
 83 
 84             default:
 85                 break;
 86         }
 87         return super.onTouchEvent(ev);
 88     }
 89 
 90     private void whetherConditionIsRight(float offset) {
 91         if (mRect.isEmpty()) {
 92             mRect.set(getLeft(), getTop(), getRight(), getBottom());
 93         }
 94         handleDefault = false;
 95         layout(getLeft() + (int) (offset * RATIO), getTop(), getRight() + (int) (offset * RATIO), getBottom());
 96     }
 97 
 98     private void onTouchActionUp() {
 99         if (!mRect.isEmpty()) {
100             recoveryPosition();
101         }
102     }
103 
104     private void recoveryPosition() {
105         TranslateAnimation ta = new TranslateAnimation(getLeft(), mRect.left, 0, 0);
106         ta.setDuration(300);
107         startAnimation(ta);
108         layout(mRect.left, mRect.top, mRect.right, mRect.bottom);
109         mRect.setEmpty();
110         handleDefault = true;
111     }
112 
113 }
原文地址:https://www.cnblogs.com/819158327fan/p/6831742.html