自定义ViewGroup

来源:互联网 发布:淘宝推荐系统 编辑:程序博客网 时间:2024/05/01 06:49

实现ScrollView的效果,且滚动带有“黏性”,滑动距离大于控件高度(屏幕高度)的1/3时,会自动滚动到上一个(下一个)控件

public class DiyViewGroup extends ViewGroup {    private int mScreenHeight;    private int mLastY;    private Scroller mScroller;    private int mStart;    private int mEnd;    public DiyViewGroup(Context context) {        super(context);        init(context);    }    public DiyViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public DiyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    // 初始化mScreenHeight和mScroller    private void init(Context context) {        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        mScreenHeight = outMetrics.heightPixels;        mScroller = new Scroller(context);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        int childCount = getChildCount();        // 对子View进行布局        for (int i = 0; i < childCount; i++) {            View child = getChildAt(i);            if(child.getVisibility() != GONE) {                child.layout(l, mScreenHeight * i, r, mScreenHeight * (i + 1));            }        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int count = getChildCount();        // 通知子View对自身进行测量        for (int i = 0; i <count ; i++) {            View childView = getChildAt(i);            // 可能子View的宽高是match_parent,所以要将父控件的宽高传进去            measureChild(childView, widthMeasureSpec, heightMeasureSpec);        }        // 设置ViewGroup自己的宽高        int width = MeasureSpec.getSize(widthMeasureSpec);        int height = mScreenHeight * count;        setMeasuredDimension(width, height);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int y = (int) event.getY();        switch(event.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.i("qqq", "onTouchEvent: down");                mLastY = y;                // 记录触摸起点                // getScrollY()从最原始位置向上滚动的距离                mStart = getScrollY();                break;            case MotionEvent.ACTION_MOVE:                Log.i("qqq", "onTouchEvent: move");                if(!mScroller.isFinished()) {                    // 停止动画,立即移动到终点位置                    mScroller.abortAnimation();                }                int dy = mLastY - y;                if(getScrollY() < 0) {                    dy = 0;                }                if(getScrollY() + mScreenHeight > getHeight()) {                    dy = 0;                }                scrollBy(0, dy);                mLastY = y;                break;            case MotionEvent.ACTION_UP:                Log.i("qqq", "onTouchEvent: up");                // 记录触摸终点                mEnd = getScrollY();                int dScrollY = mEnd - mStart;                if(dScrollY > 0) {                    if(dScrollY < mScreenHeight / 3) {                        // 第三个参数第四个参数分别是向左移动的距离和向上移动的距离                        mScroller.startScroll(0, getScrollY(), 0, -dScrollY);                    } else {                        mScroller.startScroll(0, getScrollY(), 0, mScreenHeight - dScrollY);                    }                } else {                    if(-dScrollY < mScreenHeight / 3) {                        mScroller.startScroll(0, getScrollY(), 0, -dScrollY);                    } else {                        mScroller.startScroll(0, getScrollY(), 0, -(mScreenHeight - (-dScrollY)));                    }                }                break;        }        postInvalidate();        return true;    }    @Override    public void computeScroll() {        super.computeScroll();        if(mScroller.computeScrollOffset()) {            scrollTo(0, mScroller.getCurrY());            postInvalidate();        }    }}


0 0
原创粉丝点击