美文网首页
自定义View之四-滑动相关

自定义View之四-滑动相关

作者: woochen123 | 来源:发表于2018-10-30 14:38 被阅读0次

    1 滑动的三种方式

    • scrollTo和scrollBy
    • Animation
    • LayoutParams

    1.1 scrollTo和scrollBy

    1.view视图本身是无法滑动的,滑动的是view中的内容
    2.scrollTo,scrollBy方法基于的坐标原点是view的左上角(不是屏幕左上角)

    • scrollTo
    scrollTo(-100,-100)
    

    1 scrollTo(x,y); -> x,y并不是代表坐标,而是表示偏移量
    2 从(0,0)移动到(100,100),偏移量为(-100,-100),即view的内容分别向右向下各移动100
    3 如果偏移量没有改变,那么重复调用view的内容也不会移动

    • scrollBy
    scrollBy(-100,-100)
    

    1 scrollBy(x,y)实际上就是调用了 scrollTo(mScrollX + x, mScrollY + y);
    2 mScrollX、mScrollY指view内容的原始偏移量,x,y指当前偏移量(可以理解为相对于当前位置进行偏移)

    2 滑动冲突

    2.1滑动冲突的类型

    1. 子父方向不同
    2. 子父方向相同
    3. 前两种的嵌套

    2.2滑动冲突的解决方案

    • 外部拦截法(父View做拦截判断)
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            boolean intercept = false;
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    intercept = false;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (需要拦截事件) {
                        intercept = true;
                    } else {
                        intercept = false;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    intercept = false;
                    break;
                default:
                    break;
            }
            return intercept;
        }
    

    外部拦截法需要重写onIntercerptTouchEvent(),其中对于事件序列中的ACTION_DOWN事件不能拦截(因为一旦开始拦截,后续的事件将不再会传递给子孩子了,直接由自己来处理)

    • 内部拦截法(子View请求父布局做拦截判断)
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            boolean intercept = false;
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    getParent().requestDisallowInterceptTouchEvent(true);//请求父view不拦截事件
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (父类需要此类点击事件) {
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default:
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }
    

    同时,父View需要重写onIntercerptTouchEvent

      @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                return false;
            } else {
                return true;
            }
        }
    
    

    内部拦截法需要重写dispatchTouchEvent()和父View的onInterceptTouchEvent(),其中父view不能拦截ACTION_DOWN事件,因为ACTION_DOWN事件不受requestDisallowInterceptTouchEvent()影响,一旦父布局拦截,子view将无法通过requestDisallowInterceptTouchEvent()来控制事件传递。

    相关文章

      网友评论

          本文标题:自定义View之四-滑动相关

          本文链接:https://www.haomeiwen.com/subject/ibplzftx.html