- 性别
- 保密
- 积分
- 7
- 积分
- 92
- 精华
- 0
- 阅读权限
- 20
- 注册时间
- 2012-5-19
- 最后登录
- 2013-8-17
- 帖子
- 33
- 性别
- 保密
|
本帖最后由 sky_yx 于 2015-12-30 14:07 编辑
在实现ListView下拉弹起效果,最重要的是如何监听到ListView的底部及顶部,AbstractListView的trackMotionScroll(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.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() {
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();
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;
}
};
};
}
|
|