Android中View的滑动冲突

1.解决滑动冲突是有固定的模式,常见的有内部拦截和外部拦截,只要按照这俩种模式就可以顺利解决。

处理规则

对于场景1,处理规则为:当用户左右滑动时,让外部的View拦截点击事件,当用户上下滑动时,让内部的View拦截点击事件。当产生滑动时,根据滑动的起始点与终点坐标位置,如果垂直方向滑动距离大,就判断为垂直滑动,否则判断为水平滑动。其他两种情况处理方法相似,都是从业务需求上得出相应的规则。

外部拦截发

所有的点击事件都先经过父容器拦截处理,如果父容器需要拦截就拦截,不需要就传给内部的View。伪代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<code class = "language-java hljs " public boolean onInterceptTouchEvent(MotionEvent event) {
         boolean intercepted = false ;
 
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN: {
                 intercepted = false ;
                 break ;
             }
             case MotionEvent.ACTION_MOVE: {
                 if (满足父容器的拦截要求(getX()>getY())) {
                     intercepted = true ;
                 } else {
                     intercepted = false ;
                 }
                 break ;
             }
             case MotionEvent.ACTION_UP: {
                 intercepted = false ;
                 break ;
             }
             default :
                 break ;
         }
         mLastXIntercept = x;
         mLastYIntercept = y;
         return intercepted;
     }</code>

注:
ACTION_DOWN这个事件是不能拦截的,因为一旦拦截后续的事件都会由父容器处理了。

内部拦截法

父容器不拦截任何事件,所有事件都传给子元素。如果子元素需要此事件就直接消耗,否则就交给父容器进行处理。完成这个功能需要配合requestDisallowInterceptTouchEvent()方法才可。这个方法表示是否让父容器拦截事件。伪代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<code class = "language-java hljs " > public boolean dispatchTouchEvent(MotionEvent event) {
         int x = ( int ) event.getX();
         int y = ( int ) event.getY();
 
         switch (event.getAction()) {
         case MotionEvent.ACTION_DOWN: {
             parent.requestDisallowInterceptTouchEvent( true );
             break ;
         }
         case MotionEvent.ACTION_MOVE: {
             if (满足父容器的拦截要求) {
                 parent.requestDisallowInterceptTouchEvent( false );
             }
             break ;
         }
         case MotionEvent.ACTION_UP: {
             break ;
         }
         default :
             break ;
         }
         mLastX = x;
         mLastY = y;
         return super .dispatchTouchEvent(event);
     }</code>


父容器默认拦截除了ACTION_DOWN以外的其他事件,这样子当元素调用parent.requestDisallowInterceptTouchEvent(false)时,父元素才能拦截所需的事件。

总结

解决滑动冲突有两种方法,推荐外部拦截法,实现起来简单。 本文以场景1为例做了讲解,场景2,3的做法与1类似,都是根据业务需要制定处理规则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值