自定义ListView下拉弹起效果

在实现ListView下拉弹起效果,最重要的是如何监听到ListView的底部及顶部,AbstractListViewtrackMotionScroll(int,int)方法中,分析出ListView是如何判断滑动到底部及顶部的方法。

private boolean isHeader(int deltay) {

   int firstTop = getChildAt(0).getTop();

   int effectivePaddingTop = getListPaddingTop();

   int spaceAbove = effectivePaddingTop - firstTop;

   return getFirstVisiblePosition() == 0&&spaceAbove<=0&&deltay<0;

 }

 private boolean isButtom(int deltay) {

    int lastBottom = getChildAt(getChildCount() - 1).getBottom();

    int effectivePaddingBottom = getListPaddingBottom();

    return getLastVisiblePosition() == (getCount() - 1)&&lastBottom<=(getHeight()-effectivePaddingBottom)&&deltay>0;

 }

 

通过以上两个方法可以判断ListView是否滑动到底部及顶部。
但是为了实现弹起效果,必须用到scrollBy()和scrollTo()两个方法。具体实现代码如下:

import android.content.Context;

 import android.os.Handler;

 import android.util.AttributeSet;

 import android.view.MotionEvent;

 import android.widget.ListView;

 import android.widget.Scroller;

 public class MyListView extends ListView {

 private Context mContext;

 private Scroller mScroller;

 private int mLastMotionY = 0;

 public MyListView(Context context, AttributeSet attrs, int defStyle) {

   super(context, attrs, defStyle);

   // TODO Auto-generated constructor stub

 }

 public MyListView(Context context, AttributeSet attrs) {

   super(context, attrs);

   this.mContext = context;

   mScroller = new Scroller(mContext);

 }

 public MyListView(Context context) {

   super(context);

   // TODO Auto-generated constructor stub

 }

 @Override

 public void computeScroll() {

   if (mScroller.computeScrollOffset()) {

    scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

    postInvalidate();

   }

 }

 @Override

 public boolean dispatchTouchEvent(MotionEvent event) {

   // TODO Auto-generated method stub

   int y = (int) event.getY();

   switch (event.getAction()) {

   case MotionEvent.ACTION_DOWN:

    if (mScroller != null) {

     if (!mScroller.isFinished()) {

      mScroller.abortAnimation();

     }

    }

    mLastMotionY = y;

    break;

   case MotionEvent.ACTION_MOVE:

    int deltay = (int) (mLastMotionY - y);

    mLastMotionY = y;

    if (isButtom(deltay)) {

     setVerticalScrollBarEnabled(false);

     scrollBy(0, deltay);

     return true;

    }

    if (isHeader(deltay)) {

     setVerticalScrollBarEnabled(false);

     scrollBy(0, deltay);

     return true;

    }

    break;

   case MotionEvent.ACTION_UP:

    mLastMotionY = 0;

    if (getScrollY()!=0) {

     mScroller.startScroll(0, getScrollY(), 0, -getScrollY(), 1000);

     invalidate();

     handler.sendEmptyMessageDelayed(0, 500);

     return true;

    }

    break;

   default:

    break;

   }

   return super.dispatchTouchEvent(event);

 }

 private boolean isHeader(int deltay) {

   int firstTop = getChildAt(0).getTop();

   int effectivePaddingTop = getListPaddingTop();

   int spaceAbove = effectivePaddingTop - firstTop;

   return getFirstVisiblePosition() == 0&&spaceAbove<=0&&deltay<0;

 }

 private boolean isButtom(int deltay) {

    int lastBottom = getChildAt(getChildCount() - 1).getBottom();

    int effectivePaddingBottom = getListPaddingBottom();

    return getLastVisiblePosition() == (getCount() - 1)&&lastBottom<=(getHeight()-effectivePaddingBottom)&&deltay>0;

 }



 Handler handler = new Handler(){

   public void handleMessage(android.os.Message msg) {

    int what = msg.what;

    switch (what) {

    case 0:

     setVerticalScrollBarEnabled(true);

     invalidate();

     break;

    default:

     break;

    }

   };

 };

 }

下载地址

你可能感兴趣的:(ListView)