[转]viewpager与子view的事件冲突解决

转载 2015年07月07日 15:03:14


2014-8-22阅读64 评论0

 问题:

    对android的事件机制一直不怎么了解,最近android项目中运用viewpager+listview (就是viewpager的子view中嵌套了listview),出现了触摸手势冲突

  吐槽:

  问题一来很是捉急,于是执行傻瓜式问题解决,各种谷歌大神求支援,按照网上的解决方案,也不管对不对应我的情况,一顿乱搞....

  显然无数次失败之后还是没给我足够的教训,这次结果依然是没找到现成的,(;一_一) ...

  机制:

    纠结了一天,决定好好理一理android的事件机制,找到下面这3张图原地址我没找到,已经在在谷歌大神那留下N个副本..实在没找到原作者,如有知道原创地址请与我联系,觉得豁然开朗


        

            图1                图2                        图3


  onInterceptTouchEvent 和 onTouchEvent 清楚了,还有个 dispatchTouchEvent 不太清楚,网上说是分发事件的,在调试时,我发现 viewgroup 的分发机制似乎不同(dispatchTouchEvent在onInterceptTouchEvent后调用)。

  最终找到这篇文章 "Android事件处理第一节(View对Touch事件的处理)",看到其中 View.dispatchTouchEvent() 的源码,又是豁然开朗.

复制代码
    public boolean dispatchTouchEvent(MotionEvent event) 
    {  
        if (mInputEventConsistencyVerifier != null) 
        {  
            mInputEventConsistencyVerifier.onTouchEvent(event, 0);  
        }  
  
        if (onFilterTouchEventForSecurity(event)) 
        {  
            //noinspection SimplifiableIfStatement  
            ListenerInfo li = mListenerInfo;  
            if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED  
                    && li.mOnTouchListener.onTouch(this, event))
            {  
                return true;  
            }  
  
            if (onTouchEvent(event)) 
            {  
                return true;  
            }  
        }  
  
        if (mInputEventConsistencyVerifier != null)
        {  
            mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);  
        }  
        return false;  
    } 
复制代码

  也就是说是 dispatchTouchEvent 在调用 onTouchEvent 。

  思路:

      最终效果是竖直方向滑动时listview动起来,水平方向滑动viewpager动起来,显然我需要对滑动手势进行判断,

      

     (1)  在 case MotionEvent.ACTION_DOWN: 分支获取第一次按下点的坐标
    
     (2)  在 case MotionEvent.ACTION_MOVE: 分支获取移动结束点的坐标

     (3)  通过两点横坐标差值与竖坐标的差值可以判断手势方向;

      这里我的view层次是,activity->viewpager->listview.

      所以我希望它的事件流向像下图一样


 

      


 

      思路差不多就这些.

   解决:

      直接上代码吧.

复制代码

/*  代码位置:复写ViewPager的onTouchEvent方法*/

private float xDistance, yDistance, xLast, yLast; /* (non-Javadoc) * @see android.widget.AbsListView#onTouchEvent(android.view.MotionEvent) */ @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //获取第一次按下点的坐标 xDistance = yDistance = 0f; xLast = ev.getX(); yLast = ev.getY(); break; case MotionEvent.ACTION_MOVE:        //获取移动结束点的坐标  final float curX = ev.getX(); final float curY = ev.getY();
       //差值 xDistance
+= Math.abs(curX - xLast); yDistance += Math.abs(curY - yLast); xLast = curX; yLast = curY; if(xDistance <= yDistance) return super.onTouchEvent(ev); // 消耗 else return false; // 往下传递 } return super.onTouchEvent(ev); }
复制代码

      如果你的项目,viewpager之下还有 view ,并且还有手势处理,那你可以对你想屏蔽的 view 使用 requestDisallowInterceptTouchEvent(true); ,比如说我这的Activity还有手势处理,我想屏蔽它,于是就在 viewpager 的 onInterceptTouchEvent 里调用了 getParent().requestDisallowInterceptTouchEvent(true); ,代码如下

  @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) 
    {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.onInterceptTouchEvent(arg0);
    }

      问题解决,暂时就这些了.


原文地址  http://m.blog.csdn.net/blog/u012124604/38757145

用requestDisallowInterceptTouchEvent()方法防止viewpager和子view冲突

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0803/1500.html 摘要 ViewPager来实现左右滑动切换...
  • fancylovejava
  • fancylovejava
  • 2013年10月23日 17:08
  • 10637

ViewPager子View滑动事件冲突解决

事件分发:public boolean dispatchTouchEvent(MotionEvent ev) Android事件以隧道方式逐层向下传递。事件首先由dispatchTouchEvent...
  • u014316462
  • u014316462
  • 2016年11月10日 16:48
  • 1076

[转]viewpager与子view的事件冲突解决

2014-8-22阅读64 评论0  问题:     对android的事件机制一直不怎么了解,最近android项目中运用viewpager+listview (就是viewpage...
  • autowanglei
  • autowanglei
  • 2015年07月07日 15:03
  • 392

viewpager与子view的事件冲突解决

http://www.cnblogs.com/lvzaina/p/3202220.html
  • zhuojianhai88
  • zhuojianhai88
  • 2013年12月02日 17:04
  • 321

ViewPager的使用及获取子view控件的操作(inflate)

Step 1: 布局文件中添加viewpager和切换页面button
  • phenixyf
  • phenixyf
  • 2016年05月16日 18:51
  • 4992

《View的事件体系》(五)滑动冲突

开发的时候遇到滑动冲突是很坑的,比如在界面中有内外两层可以同时滑动,这个时候就会产生滑动冲突,其实解决滑动冲突是有固定套路的,掌握了这个套路滑动冲突就好解决了。         下面先列举一下产生滑动...
  • laona_sdu
  • laona_sdu
  • 2017年03月14日 13:04
  • 74

Android——View的事件体系(三)View的滑动冲突

主要介绍内容: View的滑动冲突 常见的滑动冲突场景 滑动冲突的处理规则 滑动冲突的解决方式 上一篇博客中我们已经介绍了 View 的事件分发机制,想要了解的请戳这里:Android——View...
  • AkaiC
  • AkaiC
  • 2016年09月30日 21:16
  • 475

Android 笔记 ViewPager的滑动与子view内部滑动事件的冲突问题

ViewPager 与子view的滑动冲突在上一次笔记中建设了一个可以滑动的photoView,显示图片,可以放大,滑动大部分时候这个自定义View会和ViewPager一起使用。也就是我们通常看到...
  • super_zq
  • super_zq
  • 2016年10月13日 14:14
  • 1491

ViewPager子View滑动事件冲突解决

事件分发:public boolean dispatchTouchEvent(MotionEvent ev)Android事件以隧道方式逐层向下传递。事件首先由dispatchTouchEvent方法...
  • u012948731
  • u012948731
  • 2016年01月22日 10:53
  • 314

ViewPager与子View手势触摸冲突解决

ViewPager与子View手势触摸冲突时,可在子View触摸时加入代码getParent().requestDisallowInterceptTouchEvent(true), 可以中断pager...
  • pfugwtg
  • pfugwtg
  • 2015年01月27日 15:23
  • 292
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[转]viewpager与子view的事件冲突解决
举报原因:
原因补充:

(最多只允许输入30个字)