《Android进阶之光》Horizontal 读书笔记 - Go语言中文社区

《Android进阶之光》Horizontal 读书笔记


《Android进阶之光》Horizontal 读书笔记

滑动不超过屏幕宽度一半时

滑动超过屏幕宽度(这里 childWidth  = match_parent)一半时

public class HorizontalView extends ViewGroup {

    private int lastInterceptX;
    private int lastInterceptY;
    private int lastX;
    private int lastY;

    private int childWidth;

    private int curIndex;
    private Scroller scroller;

    //测试滑动速度
    private VelocityTracker tracker;

    public HorizontalView(Context context) {
        this(context, null);
    }

    public HorizontalView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HorizontalView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        scroller = new Scroller(getContext());
        tracker = VelocityTracker.obtain();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int widthSpec = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpec = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //若无子元素,宽高设置为0
        if (getChildCount() == 0) {
            setMeasuredDimension(0, 0);
        }
        View childOne = getChildAt(0);
        int childWidth = childOne.getMeasuredWidth();
        int childHeight = childOne.getMeasuredHeight();

        if (widthSpec == MeasureSpec.AT_MOST) {
            //若宽为 at_most , 定义宽为所有子元素的宽
            widthSize = childWidth * getChildCount();
        }

        if (heightSpec == MeasureSpec.AT_MOST) {
            //若高为 at_most 定义高为第一个子元素的高
            heightSize = childHeight;
        }
        setMeasuredDimension(widthSize, heightSize);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        int left = 0;
        View child;
        for (int i = 0; i < childCount; i++) {
            child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                int width = child.getMeasuredWidth();

                childWidth = width;

                child.layout(left, 0, left + width, child.getMeasuredHeight());
                left += width;
            }
        }
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean intercept = false;
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //滑动时再次点击停止
                intercept = false;
                if (!scroller.isFinished()) {
                    scroller.abortAnimation();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - lastInterceptX;
                int deltaY = y - lastInterceptY;
                intercept = Math.abs(deltaX) - Math.abs(deltaY) > 0;

                break;
            case MotionEvent.ACTION_UP:
                break;
        }

        lastInterceptX = x;
        lastInterceptY = y;

        lastX = x;
        lastY = y;
        return intercept;
    }


    //若 viewGroup 拦截则执行
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!scroller.isFinished()) {
                    scroller.abortAnimation();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - lastX;
                scrollBy(-deltaX, 0);
                break;
            case MotionEvent.ACTION_UP:
                int dis = getScrollX() - curIndex * childWidth;
                if (Math.abs(dis) > childWidth / 2) {
                    if (dis > 0) {
                        curIndex++;
                    } else {
                        curIndex--;
                    }
                } else {
                    tracker.computeCurrentVelocity(1000);
                    float xV = tracker.getXVelocity();
                    if (xV > 50) {
                        if (xV > 0) {
                            curIndex--;
                        } else {
                            curIndex++;
                        }
                    }
                }
                //修正curIndex
                curIndex = curIndex < 0 ? 0 :
                        curIndex > getChildCount() - 1 ? getChildCount() - 1 : curIndex;
                //处理 Action_move 滑动结果,左滑或右滑
                smoothScrollTo(curIndex * childWidth, 0);

                //重置计算器
                tracker.clear();
                break;
        }

        lastX = x;
        lastY = y;
        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate();
        }
    }

    /**
     * 弹性滑动
     */
    public void smoothScrollTo(int destX, int destY) {
        scroller.startScroll(getScrollX(), getScrollY(),
                destX - getScrollX(), destY - getScrollY(), 1000);
        invalidate();
    }
}
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/wust_xzp/article/details/78055851
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 18:51:06
  • 阅读 ( 877 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢