public class STRefreshLayout extends RelativeLayout{ private String TAG = "STRefreshLayout"; private int screenWidth = 0; private int marginTop = 0; private final int MARGIN_TOP; private Handler mHandler = new Handler(); public STRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); screenWidth = getResources().getDisplayMetrics().widthPixels; marginTop = screenWidth/2; MARGIN_TOP = marginTop; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); if (childCount>0){ View child = getChildAt(0); child.layout(0,-marginTop,r,b); } } private int mStartY = -1; private boolean isTAG = false; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: mStartY = (int)ev.getY(); break; case MotionEvent.ACTION_MOVE: int distance = (int)ev.getY()-mStartY; mStartY = (int)ev.getY(); View child = getChildAt(0); if (child instanceof ListView){ ListView list = (ListView)child; int position = list.getFirstVisiblePosition(); if (position == 0){ if (list.getChildCount() >0){ View lChild = list.getChildAt(0); int top =lChild.getTop(); int hTop = top+MARGIN_TOP; if (top ==0 && distance>0 && hTop >= MARGIN_TOP){ marginTop = marginTop-distance/3; requestLayout(); isTAG = false; return true; }else if(top ==0 && distance<0){ int temp = marginTop-distance/3; marginTop = temp>MARGIN_TOP?MARGIN_TOP:temp; if (marginTop == MARGIN_TOP){ if (!isTAG){ isTAG = true; MotionEvent e = MotionEvent.obtain(ev.getDownTime() - 100, ev.getEventTime() - 50, MotionEvent.ACTION_DOWN, ev.getX(), ev.getY(), 100); list.onTouchEvent(e); } }else { requestLayout(); return true; } } } } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (marginTop<(MARGIN_TOP*3/4) && mListener!=null && !mIsRefreshing){ mListener.refresh(); mIsRefreshing = true; } if (marginTop<MARGIN_TOP) runAnimate(); isTAG = false; break; } return super.dispatchTouchEvent(ev); } private void runAnimate(){ new Thread(){ @Override public void run() { int temp = MARGIN_TOP - marginTop; while (marginTop != MARGIN_TOP){ int p = temp/15 + marginTop; marginTop = p>MARGIN_TOP?MARGIN_TOP:p; mHandler.post(new Runnable() { @Override public void run() { requestLayout(); } }); try { sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } // mIsRefreshing = false; } }.start(); } private boolean mIsRefreshing = false; public void compelte(){ mIsRefreshing = false; } private IRefreshListener mListener; public void setRefreshListener(IRefreshListener listener){ this.mListener = listener; } public interface IRefreshListener{ void refresh(); } }