返回 登录
5

自定义ViewGroup

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();
        }
    }
}
评论