效果图
代码
public class CustomScrollView extends ViewGroup {
private final int mMScreenHeight;
private Scroller mScroller;
private int mLastY;
private int mStart;
private int mEnd;
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取屏幕高度
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
mMScreenHeight = metrics.heightPixels;
//创建Scroller对象
mScroller = new Scroller(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
//测量子View
measureChild(childView,widthMeasureSpec,heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
//设置ViewGroup的高度
MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
params.height = childCount*mMScreenHeight;
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
childView.layout(0,i*mMScreenHeight,r,(i+1)*mMScreenHeight);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int y = (int) event.getY();//当前点击的纵坐标位置
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
mLastY = y;
mStart = getScrollY();
break;
case MotionEvent.ACTION_MOVE:
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
int dy = mLastY - y;
if(getScrollY()<0){//滑动到最顶部
dy =0;
}
if(getScrollY()>getHeight() - mMScreenHeight){//滑动到最底部
dy = 0;
}
scrollBy(0,dy);//跟随手指滑动对应距离
mLastY = y;//把当前的位置赋值给上一次
break;
case MotionEvent.ACTION_UP:
mEnd = getScrollY();//手指抬起时滑动的距离
int dScrollY = mEnd - mStart;//一次滑动的距离
if(dScrollY>0){//向下滑动
if(dScrollY > mMScreenHeight/3){
mScroller.startScroll(0,getScrollY(),0,mMScreenHeight - dScrollY);
}else{
mScroller.startScroll(0,getScrollY(),0,-dScrollY);
}
}else{//向上滑动
if(-dScrollY>mMScreenHeight/3){
mScroller.startScroll(0,getScrollY(),0,-mMScreenHeight - dScrollY);
}else{
mScroller.startScroll(0,getScrollY(),0,-dScrollY);
}
}
invalidate();
break;
}
return true;
}
@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
scrollTo(0,mScroller.getCurrY());
postInvalidate();
}
}
}