按计划,今天应该介绍Android的滑动冲突的,但由于该内容涉及Android的事件分发机制,所以我先简单介绍事件分发机制,然后再介绍滑动冲突。
事件分发机制
事件分发机制就是对MotionEvent事件的分发过程。通俗点说呢,就是我们点击一下手机屏幕,然后这个点击事件由哪一个组件来处理。Android系统中就有一个机制来决定有谁来执行以及执行的顺序。这个机制有三个方法,分别是:
onInterceptTouchEvent() :对一个事件进行拦截,返回一个boolean值,true表示拦截,false表示不拦截。就是当我们点击屏幕后,会由ViewGroup来处理这个事件,首先执行这个方法,判断是否要拦截这个事件,如果拦截这个事件,机会传给 onTouchEvent() 方法进行处理,但如果不拦截,就会传给 dispatchTouchEvent() 方法进行分发给下一级组件,下级组件同样会执行相同的过程。
dispatchTouchEvent() :又来对事件进行分发,
onTouchEvent() :在dispatchTouchEvent()中运行, 对事件进行处理
读完上面的内容可能似懂非懂,没关系,只要知道三个方法的运行顺序和执行意义就行啦,下面我们进行今天的主要内容,滑动冲突。
典型的滑动冲突有两种:外部拦截法和内部拦截法。
外部拦截法(我称这为从上到下):就是当我们点击屏幕时,对最先获取到的组件设置其 onInterceptTouchEvent() 方法,根据点击事件判断是否要拦截,如果拦截,返回true,就由该组件处理,事件不再往下传,如果不拦截,返回false,事件继续往下传,直达最小的一个字组件结束。(这种方法符合事件分发机制,比较推荐)
内部拦截法(从下到上):就是当我们点击屏幕时,先从最小的子组件开始判断是否拦截,然后一级一级往上传。直达最外层的组件结束,但这种方法不符合事件分发机制,所以会稍微麻烦一点,需要配合 requestDisallowInterceptTouchEvent()方法才能正常工作。下面我们分别介绍这两种方法
案例场景,我们在一个ViewPager里面嵌套一个ViewPager,但我们滑动屏幕时,是滑动父组件还是滑动子组件呢,此时系统无法自己判断,就需要我们通过代码来帮助区分啦
首先使用外部拦截法,先由父组件进行拦截屏幕滑动事件,只需要重写onInterceptTouchEvent() 方法,当要拦截处理是就返回true,否则就返回false。
<span style="font-family:FangSong_GB2312;font-size:18px;"> public boolean onInterceptTouchEvent(MotionEvent ev) {
...
boolean intercepted=false;
switch (action) {
case MotionEvent.ACTION_Down:
intercepted=false;
break;
case MotionEvent.ACTION_MOVE:
if(父容器需要处理此事件)
intercepted=true;
else
intercepted=false;
break;
case MotionEvent.ACTION_UP: {
intercepted=false;
break;
}
...
return intercepted;
}</span>
这是第一种方法,比较方便,易懂,下面介绍第二种方法
<span style="font-family:FangSong_GB2312;font-size:18px;">public boolean dispatchTouchEvent(MotionEvent event) {
...
switch (action) {
case MotionEvent.ACTION_Down:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if(子元素需要处理此事件)
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP: {
break;
}
...
return super.dispatchTouchEvent(event);
;
}</span>
同时由于事件分发机制,我们还得设置父组件不拦截事件,
<span style="font-family:FangSong_GB2312;font-size:18px;">@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action=ev.getAction();
if(action==MotionEvent.ACTION_DOWN){
return false;
}else {
return true;
}
}</span>
好,以上就是简单的滑动冲突的介绍,跟多内容大家可以在这里学习点击打开链接
鄙人LinLitterWhite ,一个刚踏入Android领域的最新人,写博文来保存分享自己的知识,有错的地方,大家请尽情指出,鄙人必重谢。可加我微信共同学习!
微信号:wu1023q