android一个下拉放大库bug的解决过程及思考

起因

项目中要做一个下拉缩放图片的效果,搜索了下github上面,找到了两个方案。

  • https://github.com/Frank-Zhu/PullZoomView

    这个库本来做的还可以,不过有个缺陷就是,当scroolview滑动到底部,再向上拉动,会导致放大效果不连续,需要重新释放,再次下拉,这对于追求细节的我来说,不可忍受。看了半天他的代码,感觉他的实现方式很难修改为我想要的效果,后来就放弃了。

  • https://github.com/Gnod/ParallaxListView

    这个自定义view写的笔记简单,也很容易看懂,同时避免了上面那个库的问题,所以通过简单的改造,我修改成为ScrollView的方式。但是同时也碰到一个问题,那就是当ScrollView中包含的view设置了OnClickListner事件的时候,触摸事件的传递会出现问题。导致滑动出现异常。

下面就是我修改后的项目地址

PullToZoomScrollView

下面主要说明下,我在修复bug的时候的思路。

首先看下具体问题:

当scrollview 中的元素未占满scrollview的时候,在scrollivew的onInterceptTouchEvent方法中

 @Override
public boolean onInterceptTouchEvent(MotionEvent ev) { //中间代码省略 /*
* Don't try to intercept touch if we can't scroll anyway.
*/
if (getScrollY() == 0 && !canScrollVertically(1)) {
return false;
} //中间代码省略
}

有一个canScrollVertically的判断,用来返回scrollview的内容是否撑满,所以当scrollview中的元素未占满的时候,这里直接返回false,scrollview的触摸事件没有截获,直接交给了子view处理,而这个时候,子view又设置了click事件,对触摸进行了消费,所以scrollivew无法响应下拉的手势操作了。

解决思路

对于这种触摸冲突的问题,之前看《android艺术开发探索》时候,有过了解,无非就是两个,一个外部拦截,一个内部拦截。想到scrollview中的元素可能会嵌套很多类型的。所以内部拦截的方式,可能工作量很大,需要每个View做处理。所以初步锁定了外部拦截方式。

刚开始的思路也很清晰,就是当向下滑动的距离大于了TouchSlop时候,就截获事件,不向下传递,如果是点击的时候,则直接传递到下面的view进行处理。

 @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
xFirst = event.getX();
yFirst = event.getY();
mIsIntercept = false;
case MotionEvent.ACTION_MOVE:
xDistance = event.getX()-xFirst;
yDistance = event.getY()-yFirst;
if(Math.abs(yDistance)>mTouchSlop){
mIsIntercept = true;
}else {
mIsIntercept = false;
}
break;
case MotionEvent.ACTION_UP:
mIsIntercept = false;
break;
default:
break;
}
return mIsIntercept;
} @Override
public boolean canScrollVertically(int direction) {
return true;
}

可是当这样写之后,总是会抛一个错误,Invalid pointerId=-1 in onTouchEvent,到源码里面看,这个错是

@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("scrollview",event.getAction()+"");
touchListener.onTouchEvent(event);
return super.onTouchEvent(event);
}

是调用super.onTouchEvent(event)的时候抛出来的,再次查看源码,原来是scrollview里面的一个变量没有赋值,原本的赋值操作是在onInterceptTouchEvent中,但是这个函数已经被我们重写,那怎么办呢。后来想到,假如我在ACTION_DWON里面,先调用下surper.onInterceptTouchEvent(event),将变量赋值,那不就ok了,所以最后的代码结果是

 @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
xFirst = event.getX();
yFirst = event.getY();
mIsIntercept = false;
//这句话是关键
super.onInterceptTouchEvent(event);
case MotionEvent.ACTION_MOVE:
xDistance = event.getX()-xFirst;
yDistance = event.getY()-yFirst;
if(Math.abs(yDistance)>mTouchSlop){
mIsIntercept = true;
}else {
mIsIntercept = false;
}
break;
case MotionEvent.ACTION_UP:
mIsIntercept = false;
break;
default:
break;
}
return mIsIntercept;
} @Override
public boolean canScrollVertically(int direction) {
return true;
}

同时我们也将canScrollVertically这个函数直接返回true,即不让super.onInterceptTouchEvent(event);调用的时候直接返回false

这样我就完美的解决了事件的分发处理与Invalid pointerId=-1 in onTouchEvent这个问题。

总结

上述的问题,大概经过了两天的各种尝试,才得到结果。而且灵感是在回家之后,不经意的一个瞬间,想到的,所以有时候,遇到问题,自己可以暂时先放一放,换个时间思维角度也许就大不一样,问题也就迎刃而解。

转载请注明出处

http://www.cnblogs.com/gaoteng/p/5485634.html

http://www.gaotenglife.com/?p=382

android一个下拉放大库bug的解决过程及思考的更多相关文章

  1. Android-PullToRefresh下拉刷新库基本用法

    How:(使用) 转自:http://blog.csdn.net/hantangsongming/article/details/42490277 PullToRefresh是一套实现非常好的下拉刷新 ...

  2. Xamarin. Android实现下拉刷新功能

    PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

  3. Android智能下拉刷新加载框架—看这些就够了

    一些值得学习的几个下拉刷新上拉加载开源库 Android智能下拉刷新框架-SmartRefreshLayout 支持所有的 View(AbsListView.RecyclerView.WebView. ...

  4. Android原生下拉刷新SwipeRefreshLayout实践

    本篇文章翻译自Ravi Tamada的Android Swipe Down to Refresh ListView Tutorial 首先来看一下效果图 你应该发现很多的android app比如Tw ...

  5. IOS下拉放大图片

    代码地址如下:http://www.demodashi.com/demo/11623.html 一.实现效果图 现在越来越多的APP中存在下拉放大图片的效果,今天贡献一下我的实现这种方法的原理,和我遇 ...

  6. Android SwipeRefreshLayout 下拉刷新——Hi_博客 Android App 开发笔记

    以前写下拉刷新 感觉好费劲,要判断ListView是否滚到顶部,还要加载头布局,还要控制 头布局的状态,等等一大堆.感觉麻烦死了.今天学习了SwipeRefreshLayout 的用法,来分享一下,有 ...

  7. Android 自定义下拉刷新ListView

    package com.dwtedx.qq.view; import android.content.Context; import android.util.AttributeSet; import ...

  8. android实现下拉框(spinner),自己定义大小颜色背景位置,去掉默认样式黑边

    1. 实现最简单的spinner xml文件,有一个TextView,一个Spinner: <RelativeLayout xmlns:android="http://schemas. ...

  9. Android Spinner 下拉框简单应用 详细注解

    目录 Android Spinner 代码部分 Spinner代码介绍 核心代码 说在最后 @ Android Spinner Spinner 提供下拉列表式的输入方式,该方法可以有效节省手机屏幕上的 ...

随机推荐

  1. phpstrom设置php环境

    phpstorm设置自动同步服务器 Tools->Deployment->Confinguration 点+号,添加服务器,类型SFTP,输入name 点击ok,项目与服务器连接成功! 设 ...

  2. 小J学python--Exception-异常

    现在我们要打开一个名为fuck的文件,fuck是不存在的,看看异常是怎么工作的 不捕获异常的情况 #打开文件 open('fuck') 执行结果 捕获所有异常 Exception是所有异常类的父类,所 ...

  3. [BZOJ 4573][ZJOI 2016]大森林

    [LOJ 2092][BZOJ 4573][UOJ 195][ZJOI 2016]大森林 题意 给定一个树序列, 初始时所有树都只有一个点, 要求支持三种操作: 区间种树(在某个特定点上长出一个子结点 ...

  4. 初进MFC的世界,太奇妙。第六次作业----未完待续

    又一次的迁徙.我希望能够早些抵达. 第六次作业-未完待续!图形界面,计算器文件 本次的作业是给自己的计算器加一个可视化的窗口,我开始也是很激动和憧憬的,看了很多的界面库,发现并没有想象的那么简单,因为 ...

  5. Union Find

    并查集 前言 来自知乎,Coursera 上普林斯顿大学的算法公开课,稍微来博客上写写记记. 课程资源:1. Algorithms, Part I 2. Algorithms, Part II 3. ...

  6. Java遇到的问题、错误——持续更新

    内容:dead code.关于eclipse没有js代码提示的解决 持续更新 ######################################################## dead ...

  7. Linux性能测试工具

    Linux性能测试工具 在测试中,我们不仅需要查看系统日志信息,而且还要使用大量的性能监测工具来关注某些地方,如内存.CPU等.在Linux系统中,所有的运行参数保存在虚拟目录/proc中,换句话说, ...

  8. H3C笔试题目

    最近这段时间正在找工作,去H3C做了下笔试题,题目出的还不错,比一般公司水平高上一点点,偷偷弄了点回来,分享一下,我把答案和解析全部整理了出来,有需要的可以看看. 1.以下描述正确的有(AD) A.1 ...

  9. JavaScript的DOM_通过计算后样式来获取

    虽然可以通过 style 来获取单一值的 CSS 样式,但对于复合值的样式信息,就需要通过计算样式来获取. DOM2 级样式,window 对象下提供了 getComputedStyle()方法.接受 ...

  10. MySQL查询时强制区分大写和小写

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zyb_icanplay7/article/details/24981791 平时非常少会考虑数据存储 ...