浅谈网上的zoomlistview存在的问题
最近项目主要是做一个类似wps文档阅历的功能,以列表的形式显示文档,并且需要实现缩放平移。而网上关于此类功能的实现主要是通过自定义的listview实现的,类名为ZoomListView。
网上的zoomlistview模板大多是一套,主要核心代码就是以下:
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save(Canvas.MATRIX_SAVE_FLAG);
if (mScaleFactor == 1.0f) {
mPosX = 0.0f;
mPosY = 0.0f;
}
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
invalidate();
}
该函数主要实现了对整体列表的缩放和平移。但是mPosY的值影响了判断当前显示的第一个item,而且当你惯性滑动时,永远滑不到底。所以如何解决这两个问题呢。
解决第一个问题很简单,canvas.translate(mPosX,0),就可以了。而此时由于没有了纵向的平移,列表肯定会显示不全了。
如何解决列表显示不全的问题呢。究其原因是因为滚动条滚不到底的原因。由于此时网上也没有这方面的资料,写ZoomListView的大佬也找不到本人,后来的人估计也是copy然后写文章的,问他们其实也都不知道。于是我决定自己看源码解决问题。
根据代码跟踪发现了滚动的时候会调用trackMotionScroll函数,其中有这么一串代码:
final boolean cannotScrollDown = (firstPosition == 0 &&
firstTop >= listPadding.top && incrementalDeltaY >= 0);
final boolean cannotScrollUp = (firstPosition + childCount == mItemCount &&
lastBottom <= getHeight() - listPadding.bottom && incrementalDeltaY <= 0); if (cannotScrollDown || cannotScrollUp) {
return incrementalDeltaY != 0;
}
其中cannotScrollUp就是不能向下滚动。看这个式子有没有发现什么问题,判断不能向下滚动的条件是lastBottom <= getHeight() - listPadding.botoom。于是我突发奇想设置paddingbottom的值就好了。设置paddingbottom为对应值后,发现真的可以滚动了,太棒了,问题基本上解决了。
后来发现又有bug了,在paddingbottom部分居然不能滚动!不能滚动!不能滚动!!!哎,详细也正常,padingbottom本来就是不能滚动的,这时候怎么办呢。然后调试进入ontouchevent函数中,发现触摸该区域其实还是可以会调touchevent事件的。于是我有想到了一个奇妙的方法去解决问题。自己在touchevent中先对ev的y值进行位移,这样该区域就可以滚动了。
终于解决问题了,经过这一次我明白了一个道理,当你遇到问题的时候,一定要解析问题所在,然后跟踪深入源码,只有知道底层代码才能更好的解决问题。
想要源码的可以评论,在这里就不贴了。
这几天又来了一个需求,如何保证中心缩放。这个就有点难了,如何在这个类上修改呢。第一步就是需要优化在双指缩放的时候不能平移画布。这个问题横向的时候好解决,只要判断是否是单指就行了。横向的时候就需要禁用滚动来判断,函数setenable。
第二步就是找推导公式,进行算出新的平移。以下是纵向调整平移的代码。
//求y0的推导公式,view是对应中心点item的view。
/*
(view.top + y0)*mOldScaleFactor = cy;
(view.top(新)+y0)*mScaleFactor = cy;
先求出view.top(新),然后计算出view.top(新)与view.top之间的差。
然后求得firstitem的view.top(新的值),最后通过setSelectionFromTop滚动到对应区域
*/
int iFirstItem = getFirstVisiblePosition();
int iFirstViewTop = 0;
for(int iCnt=0;iCnt<getChildCount();++iCnt)
{
View view = getChildAt(iCnt);
if(0==iCnt)
{
iFirstViewTop = view.getTop();
}
int iViewTop = (int)(view.getTop()*mOldScaleFactor);
int iViewBottom = (int)(view.getBottom()*mOldScaleFactor);
if(iViewTop<=cy && cy<=iViewBottom)
{
int iNewViewTop = (int)(cy/mScaleFactor - (cy/mOldScaleFactor-iViewTop));
int iNewFirstViewTop = iFirstViewTop + (iNewViewTop-iViewTop);
if(0==iFirstItem && iNewFirstViewTop>=0)
{
iNewFirstViewTop = 0;
}
setSelectionFromTop(iFirstItem,iNewFirstViewTop);
break;
}
}
主要要算出当前点会平移多少,然后通过setSelectionFromTop来校准。终于经过千辛万苦,把缩放的listview完成的总算可以了!!!
浅谈网上的zoomlistview存在的问题的更多相关文章
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Android应用安全开发之浅谈加密算法的坑
<Android应用安全开发之浅谈加密算法的坑> 作者:阿里移动安全@伊樵,@舟海 阿里聚安全,一站式解决应用开发安全问题 Android开发中,难免会遇到需要加解密一些数据内 ...
- 浅谈php生成静态页面
一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权 ...
- 浅谈HTTPS以及Fiddler抓取HTTPS协议
最近想尝试基于Fiddler的录制功能做一些接口的获取和处理工作,碰到的一个问题就是简单连接Fiddler只能抓取HTTP协议,关键的登录请求等HTTPS协议都没有捕捉到,所以想让Fiddler能够同 ...
- 浅谈struts2之chain
转自:http://blog.csdn.net/randomnet/article/details/8656759 前一段时间,有关chain的机制着实困绕了许久.尽管网上有许多关于chain的解说, ...
- Android性能优化的浅谈
一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...
- 【转】 浅谈Radius协议
浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报 分类: Radius协议分析(6) 从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...
- 转:浅谈Radius协议 -来自CSDN:http://blog.csdn.net/wangpengqi/article/details/17097221
浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报 分类: Radius协议分析(6) 从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...
- 【转】Android Canvas的save(),saveLayer()和restore()浅谈
Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22 阅读:1445 评论:0 收藏: ...
随机推荐
- Eclipse+Maven(webapp)+Jetty+JReBel的配置方法
maven配置 省略 jrebel配置 jrebel毋须繁琐的配置,把jrebel-5.6.3-crack.zip解压放在磁盘文件夹就可以.(笔者路径为:D:\coding-life\IDE\jreb ...
- 2016/2/25 onchange 应用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Django的缓存,序列化,ORM操作的性能
1,缓存:把数据先保存在某个地方,下次再读取的时候不用再去原位置读取
- python库学习笔记——爬虫常用的BeautifulSoup的介绍
1. 开启Beautiful Soup 之旅 在这里先分享官方文档链接,不过内容是有些多,也不够条理,在此本文章做一下整理方便大家参考. 官方文档 2. 创建 Beautiful Soup 对象 首先 ...
- hdu5335(搜索)
Walk Out Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- Java:目录
ylbtech-Java:目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbtech. ...
- JavaScript 算法与数据结构(转载)
JavaScript 算法与数据结构 https://github.com/trekhleb/javascript-algorithms/blob/master/README.zh-CN.md
- Phpspy 2011继续身份验证绕过漏洞
Author: Tm3yShell7 官方目前下载已经修补上了 目前官方下载是2011.php, 文件名为2011ok.php的是带洞版本. 今天m0r5和我说phpspy2011 我都不知道2011 ...
- bzoj 2303: [Apio2011]方格染色【并查集】
画图可知,每一行的状态转移到下一行只有两种:奇数列不变,偶数列^1:偶数列不变,奇数列^1 所以同一行相邻的变革染色格子要放到同一个并查集里,表示这个联通块里的列是联动的 最后统计下联通块数(不包括第 ...
- concurrent包下的Exchanger练习
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据. 当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exc ...