http://blog.csdn.net/d_dmelon/article/details/51708660
瞎解析,大家看不懂的话还是看看开发艺术里的View绘制过程,自己对着代码很快能理一遍的。因为要做的项目要用到ListView里边嵌套一个HorizontalScrollView,所以会有触摸冲突。而且他这个ListView没有实现setSelection方法。直接上代码吧。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getRawY()<1220){
// boolean handled = super.dispatchTouchEvent(ev);
// handled |= mGesture.onTouchEvent(ev);
// return handled;
boolean handled = false;
handled = mGesture.onTouchEvent(ev);
return handled;
}
return super.dispatchTouchEvent(ev);
}
根据getRawY得到触摸高度,判断是响应ListView的Item还是Item布局里的ScrollView。如果小于1220,那么就是滑动ListView的Item,return mGesture.onTouchEvent(ev); ,大于就调用super.dispatchTouchEvent;这个没深入去看,但是直接返回false或者true发现并不能移动。。。有知道的请告诉我。。。
实现setSelection
@Override
public void setSelection(int position) {
//TODO: implement
}
public synchronized void scrollTo(int x) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0);
requestLayout();
}
public synchronized void scrollTo(int x , int dura) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0,dura);
requestLayout();
}
在他原有的scrollTo函数加上一个dura参数
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
mMode = SCROLL_MODE;
mFinished = false;
mDuration = duration;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartX = startX;
mStartY = startY;
mFinalX = startX + dx;
mFinalY = startY + dy;
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
}
duration是时续时间,1000的话就是1s内滑到某个距离。所以
@Override
public void setSelection(int position) {
//TODO: implement
int pos = position*1000;
scrollTo(pos,0);
}
还有就是弹性滑动的设置
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
int isHalfItem = -(mDisplayOffset-500)/1000;
int pos = isHalfItem*1000 ;
scrollTo(pos,800);
// setSelection(isHalfItem);
return true;
// return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}
mDisplayOffset在第一个item是0~-1000,第二个是-1000~-2000,以此类推可以求得当前出在第几个Item,四舍五入一下,起到滑超过一半才能移到下一个Item,不然又弹回去到当前item的起始位置。