浅谈网上的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 收藏: ...
随机推荐
- FileWriter简单用法并记录日志
import java.io.*; import java.util.Date; /** * Created by Administrator on 2018/4/6. */ public class ...
- 最齐全的站点元数据meta标签的含义和使用方法
最齐全的站点元数据meta标签的含义和使用方法 随着HTML5的流行和Web技术的不断演变,Meta标签队伍也越来越壮大,从Windows XP的IE6到现在Windows 7.Windows 8的I ...
- 头文件与cpp文件为什么要分开写
最表面的机制是: 头文件是程序的界面(是代码界面),提供给程序员以 类.模版.函数等一系列的声明,让程序员知道应该怎么调用里面的"东西". 从动态链接库的角度看: 头文件提供界面 ...
- Java反射的基本应用
反射机制,程序在运行时加载新的类,使程序更加灵活 public class HelooReflect { public static void main(String[] args) { // 获取类 ...
- java修改linux文件
package vedio.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fil ...
- BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图
BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2, ...
- 【转】js中15个常用的正则表达式+正则集合
1 用户名正则 //用户名正则,4到16位(字母,数字,下划线,减号) var uPattern = /^[a-zA-Z0-9_-]{4,16}$/; //输出 true console.log(uP ...
- win7上安装macaca的报错问题
macaca网上的各种教程中,都建议使用淘宝源安装macaca,使用淘宝源就需要先安装cnpm,在win7上切换到淘宝源安装cnpm后(npm install -g cnpm --registry=h ...
- JS获得本月的第一天和最后一天
<script> //本月第一天 function showFirstDay() { var Nowdate=new Date(); var MonthFirstD ...
- 摘抄 - JavaScript JSON的总结
JSON 是用于存储和传输数据的格式,通常用于服务端向网页传递数据 什么是 JSON? JSON英文全称 JavaScript Object Notation(JavaScript 对象表示法),是一 ...