浅谈网上的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 收藏: ...
随机推荐
- [Sciter] Script与Native交互
原帖地址:http://www.cnblogs.com/yinxufeng/p/5653920.html Script与Native交互基础简化方式Script调用NativeNative调用Scri ...
- javaScript定义函数的三种方式&变量的作用域
一.函数定义 方式1.普通方式定义函数 function 函数名(參数n){ 函数体 } function add(a,b){ return a+b; } 方式2.直接量定义函数 var 函数名=fu ...
- 对ASP.NET MVC 的路由一点理解
这个东西,真搞不懂.看了网上的教程和文章,也不懂(也不清楚写那些文章的人自己是否真的懂).只好靠自己一顿乱摸索. 好比说,下面这个路由: //路由1 config.Routes.MapHttpRout ...
- form之action的绝对路径与相对路径(转载)
1.当你的form要提交到你自己的站点之外的URL的时候,就采取绝对路径: <form action="http://www.xxx.yyy:zzzz/mmm/nn/kkk.jsp&q ...
- HBase使用教程
1 基本介绍 1.1 前言 HBase – Hadoop Database.是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文"Bigta ...
- I.MX6 Android can-utils 移植
/******************************************************************* * I.MX6 Android can-utils 移植 * ...
- BZOJ_3881_[Coci2015]Divljak_AC自动机+dfs序+树状数组
BZOJ_3881_[Coci2015]Divljak_AC自动机+dfs序+树状数组 Description Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是 ...
- 《JAVA与模式》之解释器模式
解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 解释器模式的结构 下面就以一个示意性的系统为例 ...
- vue 基础知识随笔
在vue2.0中一个vue实例的生命周期中已经没有ready()了,在vue1.0中才有ready();在vue2.0中立即执行函数使用mounted v-for 参数顺序更新: 数组中使用(valu ...
- java.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnv
转自:https://blog.csdn.net/u012941811/article/details/16960493 ava.lang.NoSuchMethodError: org.springf ...