HorizontalScrollView及ScrollView解决滑动冲突

来源:互联网 发布:致远a6协同办公软件 编辑:程序博客网 时间:2024/06/16 05:05

一、在很多的形情之下,用到ScrollView的必定会遇到滑动冲突。

解决方法有可以把ScrollView的滑动设为禁止:

        //禁止scrollview 的滑动        scrollView.setOnTouchListener(new View.OnTouchListener() {           @Override           public boolean onTouch(View view, MotionEvent motionEvent) {                return true;            }        });
这样ScrollView的滑动功能就会失效。

但这只是表面上的在整个view的传递中,Touch事件还是会被ScrollView或者HorizontalScrollView所消费掉。ScrollView或HorizontalScrollView包裹的子view就不会接收到Touch事件。所以在子view中无法进行其他关于Touch事件的操作。

要解决事件传递,创建一个HorizontalScrollView或ScrollView的子类继承其全部功能,在这基础上重写onInterceptTouchEvent()方法,把返回值直接置为false。则Touch事件就会经由控件基础上传递到包裹的子view中。等view消费了事件之后则解决了这个ScrollView不往下传事件的问题:

** * @author wangyao * @package  * @date 2017/8/2  15:58 * @describe 用于解决HorizontalScrollView横向滑动的拦截的问题 * @project */public class MyHorizontalScrollView extends HorizontalScrollView {    public MyHorizontalScrollView(Context context) {        super(context);    }    public MyHorizontalScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        return true;    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return false;    }}


二、

1、在事件的传递中经常用到的三个方法是:dispatchTouchEvent():事件是否往下(子view)去分发;onInterceptTouchEvent():事件的拦截,事件是否在这里拦截或者是往下传递;onTouchEvent():事件的消费处理,如此为止消费掉则一个事件的过程完毕。

2、一个事件是先由父View->子View往下传的;

3、如所有的子View的onTouchEvent()都不消费,这个事件再由子View逐层传给父View这要看onTouchEvent()方法去不去消费事件;


三、进行HorizontalScrollView手势的拦截的demo:

需求:在HorizontalScrollView中进行双指滑动HorizontalScrollView跟随着手势滑动,单指滑动的事件自己不处理,留给其子view进行手势的处理。

思想:在自定义MyHorizontalScrollView中的onInterceptTouchEvent()的方法里进行处理事件拦截的条件。

代码:

package com.example.administrator.canvasdemo.view;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.HorizontalScrollView;/** * @author wangyao * @package com.example.administrator.canvasdemo.view * @date 2017/8/29  20:31 * @describe TODO * @project */public class MyHorizintalScrollView extends HorizontalScrollView {    private boolean isDragCanvsMode;    private boolean isDoubleDrag = false;    private float mStartDownX;    private float mStartDownY;    private float mMoveDragCanvsX;    private float mMoveDragCanvsY;    public MyHorizintalScrollView(Context context) {        super(context);    }    public MyHorizintalScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyHorizintalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        //多点拖动的操作        switch (event.getAction()&MotionEvent.ACTION_MASK){            case MotionEvent.ACTION_DOWN:{//                Log.i("everb","按下去:"+mStartDownX);            }            break;            case MotionEvent.ACTION_POINTER_DOWN:{                isDoubleDrag = true;            }            break;            case MotionEvent.ACTION_MOVE:{//                Log.i("everb", "canvas scrollview onTouchEvent:" + event.getX() + " " + event.getY() + " event.getAction(): " + event.getAction()+ " isDoubleDrag:"+isDoubleDrag);                mMoveDragCanvsX = event.getX();                Log.i("everb","move的值:"+mMoveDragCanvsX);                float canvsMoveX = mMoveDragCanvsX - mStartDownX;                Log.i("everb","移动的值:"+canvsMoveX);                //双指滑动的距离进行双指滑动HorizontalScrollView也进行随手势滑动                this.scrollBy(-(int)canvsMoveX,0);            }            break;            case MotionEvent.ACTION_CANCEL:{                isDoubleDrag = false;//                Log.i("everb", "canvas scrollview onTouchEvent:ACTION_CANCEL");            }            break;        }        mStartDownX=mMoveDragCanvsX;        return false;    }    @Override    public boolean onInterceptTouchEvent(MotionEvent event) {        switch (event.getAction()&MotionEvent.ACTION_MASK){            case MotionEvent.ACTION_DOWN:{                mStartDownX = event.getX();                isDragCanvsMode=false;            }            break;            case MotionEvent.ACTION_POINTER_DOWN:{                //多指按下的识别                isDragCanvsMode=true;            }            break;        }//        Log.i("everb","canvas scrollview onInterceptTouchEvent:"+event.getX()+" "+event.getY() + " event.getAction()"+event.getAction());        if(isDragCanvsMode == false){            //如单指按下则事件不拦截,把事件传递到子view中            return false;        }//        Log.i("everb","canvas scrollview onInterceptTouchEvent:"+event.getX()+" "+event.getY() + " event.getAction()"+event.getAction());        //如是双指按下则返回true,把事件拦截在自己的onTouchEvent进行处理        return true;    }}


阅读全文
1 0
原创粉丝点击