1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| public class PullDownViewGroup extends ViewGroup { private static final String TAG = PullDownViewGroup.class.getSimpleName();
private static final float DAMPING = 1.5f;
private View mContentView; private View mHeaderView;
private Scroller mScroller; private int mTouchSlop;
private float mDownY;
private float mLastMoveY;
private float mCurDownY;
private float mDeltaY;
private boolean isShowHeader = false;
public PullDownViewGroup(Context context) { this(context, null); }
public PullDownViewGroup(Context context, AttributeSet attrs) { this(context, attrs, 0); }
public PullDownViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); mScroller = new Scroller(getContext()); }
@Override protected void onFinishInflate() { super.onFinishInflate(); int childCount = getChildCount(); if (childCount == 2) { mHeaderView = getChildAt(0); mContentView = getChildAt(1); } else { throw new InflateException("Must have two children."); } }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); measureChildren(widthMeasureSpec, heightMeasureSpec); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mHeaderView.layout(0, -mHeaderView.getMeasuredHeight(), mHeaderView.getMeasuredWidth(), 0); mContentView.layout(0, 0, mContentView.getMeasuredWidth(), mContentView.getMeasuredHeight()); }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mDownY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: mLastMoveY = ev.getRawY(); int mRealTouchSlop = (int) Math.abs(mLastMoveY - mDownY); if (mRealTouchSlop > mTouchSlop) { return true; } break; } return super.onInterceptTouchEvent(ev); }
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: mCurDownY = event.getRawY(); mDeltaY = mCurDownY - mLastMoveY; Log.e(TAG, "mCurDownY:" + mCurDownY + " mLastMoveY:" + mLastMoveY + " mDeltaY:" + mDeltaY + " getScrollY:" + getScrollY()); if ((!isShowHeader && mDeltaY < 0) || (isShowHeader && mDeltaY > 0)) { return true; }
scrollBy(0, (int) (-mDeltaY / DAMPING)); mLastMoveY = mCurDownY;
if (getScrollY() < 0 && mDeltaY > 0 && -getScrollY() >= 300 && !isShowHeader) { invalidate(); isShowHeader = true; mScroller.forceFinished(true); int dy = -mHeaderView.getMeasuredHeight() - getScrollY(); Log.d(TAG, "下拉dy: " + dy); mScroller.startScroll(0, getScrollY(), 0, dy); return true; }
if (getScrollY() < 0 && mDeltaY < 0 && mHeaderView.getMeasuredHeight() - Math.abs(getScrollY()) > 300 && isShowHeader) { invalidate(); isShowHeader = false; mScroller.forceFinished(true); int dy = mContentView.getMeasuredHeight() + getScrollY(); Log.d(TAG, "上拉dy: " + dy); mScroller.startScroll(0, getScrollY(), 0, -getScrollY()); return true; }
break; case MotionEvent.ACTION_UP: if ((Math.abs(getScrollY()) >= 300 && !isShowHeader) || (Math.abs(getScrollY()) <= mHeaderView.getMeasuredHeight() - 300 && isShowHeader) || !mScroller.isFinished() || mScroller.computeScrollOffset()) { return true; }
invalidate(); if (isShowHeader && mHeaderView.getMeasuredHeight() - Math.abs(getScrollY()) < 300) { mScroller.startScroll(0, getScrollY(), 0, -mHeaderView.getMeasuredHeight() - getScrollY()); }
if (!isShowHeader && Math.abs(getScrollY()) < 300) { mScroller.startScroll(0, getScrollY(), 0, -getScrollY()); } break; } return super.onTouchEvent(event); }
@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } } }
|