美文网首页
还是要Debug源码--解决Invalid pointerId=

还是要Debug源码--解决Invalid pointerId=

作者: mrz_233333 | 来源:发表于2017-12-09 13:20 被阅读0次

    项目中需要一个 股票列表 横向纵向一起联动的效果,如下图
    (借用http://blog.csdn.net/chengxu_hou/article/details/62422027 的图)

    20170316212433448.gif

    在github里面寻觅很久,找到了https://github.com/monkeyLittleMonkey/ListViewHorizontalScrollDemo

    反编译了腾讯自选股的apk,发现两者实现是差不多的,都是ListView+自定义的HorizontalScrollView为核心,加上外部嵌套拦截的LinearLayout,虽然只有8stars,没有closed Issue,项目紧,我还是用了。

    然后开始爬坑。
    没有下拉刷新? 加之...
    头部Header区域 无法点击? 改造拦截的LinearLayout,onInterceptTouchEvent return false
    直到... 差不多 快完成了,发现... 埃? 怎么左右 无法滑动了? 刚刚开始的时候还能滑,咋写完了 不能滑了?

    先是一通胡乱的尝试...
    分析了一下 我的项目与 ListViewHorizontalScrollDemo的区别
    1.控件是通过 横滑listview--带动头部header的HorizontalScrollView滑动,然后头部的header里有一个observor 持有当前页面所有item的HorizontalScrollView引用,因此可以带动当前页面所有HorizontalScrollView的横向滑动。既然滑动事件被拦截了,那么可能是头部设置了OnClick事件引起的
    去掉点击事件。。
    不行
    2.难道不成是XListView的下拉刷新拦截了事件? 去掉下拉刷新。

    不行
    3.我设置了TouchDelegate增加点击区域,难道是这个? 这个的具体实现源码也懒得看了,先去掉试试

    不行

    4.取消掉头部的改造拦截的LinearLayout..

    不行

    5.难道布局xml里的 focusable ,blocksDescendants设置了也影响了?去掉去掉

    不行

    6.难道我在修改自定义HorizontalScrollView的注释的时候删掉了 某行代码?
    打开svn提交记录 仔细比对。
    没有

    7.我觉得 我整个项目已经改造得跟github的demo一样了,demo 可以横向滑动,我依然不行。

    8.我检出了项目两天前刚开始增加此自定义HorizontalScrollView的版本。运行...是可以横滑的

    但是这两天我提交十多处涉及view事件处理的代码,我没办法知道是哪行影响了。

    还好是有Log的
    HorizontalScrollView Invalid pointerId=-1 in onTouchEvent

    我发现了我的项目与demo不同的是,我一旦触摸横向滑动,会报这个错误。
    很大程度不能横向滑动与这个错误有关。

    于是根据错误搜索到了一篇相似场景的文章:
    http://blog.csdn.net/a405942873/article/details/40264685
    大致看了一下,他是HorizontalScrollView 里嵌套了一个类似viewpager的view。然后滑动报错,然后那位博主通过查看源码 发现是:
    由于没有调用 super.onInterceptTouchEvent(); 造成 mActivePointerIdactivePointerIndex的值不能正确获取。 导致父类 onTouchEvent取值错误,最终 onTouchEvent不能正确执行。 解决方法: 解决方法很简单,只要在重写过的 onInterceptTouchEvent里面 添加 super.onInterceptTouchEvent();既可。

    很明显他的出错场景虽然类似,但是确实是不同。且,demo中本来就没有调用
    super.onInterceptTouchEvent()一样能滑动。
    10.但是抱着侥幸心理的我还是蠢呵呵的去加了一行super.onInterceptTouchEvent()
    ---ok,果然是依然不行。

    此时已经差不多浪费了一天的时间,其实我早就应该觉悟,早就应该跟这个博主一样去debug 源码 而不是 到处乱猜了。
    然而一是感觉时间紧,公司没有谷歌亲儿子Nexus机,也没空去弄 API 25的模拟器来DEBUG。

    还是拿一个比较新的Android 6.0 小米机 来Debug HorizontalScrollView把

    image.png

    大致代码行号虽然相差很多,但不至于太离谱。

    通过我的项目与demo 的debug对比发现,确实是在调用 onTouchEvent的时候,我的项目mActivePointerId=-1 而demo里的mActivePointerId=0

    大致查了一下,mActivePointerId的赋值有好几处,onInterceptTouchEvent和onTouchEvent里都有赋值。但是小米手机与源码不一致,我也没法精确确定到底源码里哪处代码影响了HorizontalScrollView里哪个方法对mActivePointerId的赋值。

    那只能玩暴力的了。我在自定义的HorizontalScrollView的onTouchEvent里增加了

            int mActivePointerId = (int) getFieldValue(this, "mActivePointerId");
            if (mActivePointerId==-1){
                setFieldValue(this,"mActivePointerId",0);
            }
    

    getFieldValue,setFieldValue为反射工具类方法
    反射强制修改mActivePointerId的值为0。

    11.这次确实证明 比较接近真相了。确实可以滑动了。但是,当我手指触摸item的时候,item会跳一下,然后再开始随着手指滑动。因此我这么改还是不行。猜测大概是DOWN事件的坐标没有记录下来传递给HorizontalScrollView

    我觉得我真的早就应该拿模拟器精确来DEBUG源码了...
    我早就应该理解...
    磨刀不误砍柴工这句古训背后所饱含的...
    古人对生活的深刻理解和感悟...

    我在下班前下载好API25 arm 的image... 得了,还是回家debug 源码吧。

    运行模拟器,运行demo...滑动...
    ok.API一致源码一致debug起来真是爽,再也不用乱猜了。发现是:


    image.png

    ACTION_DOWN的时候mActivePointerId进行了赋值,之后就一直是0 了。

    开始运行我的项目,矮??HorizontalScrollView一开始接收到的时间就是MOVE,模拟器有问题?? 再试,还是只有MOVE,MOVE中没有mActivePointerId进行赋值的代码。

    Finally,debug源码仅仅5分钟,我就终于知道是DOWN事件没有传递给HorizontalScrollView导致了mActivePointerId没有被赋值 一直报错。。

    那么我瞬间就想到了... 我在item条目的convertVIew设置的点击事件(onClickListener)是不是拦截了DOWN?
    妈蛋,去掉了那么多代码,怎么没想到这里。去掉之....
    12.万万没想到,只花了10分钟debug源码,我就终于还是解决了这个问题。滑动起来非常的smooth...

    那么convertVIew点击事件去掉了,我哪设置点击事件去呢。
    listview.setonItemCLickListener...的实现似乎是与onClickListener不同的,试试,发现可行。我才终于想起来 反编译腾讯自选股apk后发现在activity里面listview.setonItemCLickListener而不是在adapter里面对convertView 进行setOnClickListener确实是有原因的。。。

    啥也不说了,我决定 想办法刷一个原生的andriod系统来debug in order to SAVING LIFE。

    相关文章

      网友评论

          本文标题:还是要Debug源码--解决Invalid pointerId=

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