View的滚动原理简单解析(二)
来源:互联网 发布:淘宝网不显示惠惠比价 编辑:程序博客网 时间:2024/05/17 08:22
在《View的滚动原理简单解析》一文中对scrollBy和scrollTo做了简单的说明,通过该文可以对scrollTo/scollBy方法有了直观的理解。但是有个小问题就是scrollTo方法在滚动的过程中由于是瞬间的移动到目标坐标点,所以我们没法在滚动的过程中做任何控制,这个在体验上来说肯定不是那么的友好。那么如果我们想在滚动的过程中做某些滚动的特效,该怎么实现呢?这就是这篇博文的主角Scroller的用武之地。今天这篇博文就对Scroller这个类在来一个简单的说明,跟上篇博文一样文章的最后也会提供一个小小的例子demo来加深理解和应用。
在Scroller的众多方法中,有两个方法最主要,翻开网上的各种博客都少不了这两个方法的身影,这两个分方法就是startScroll()和computeScrollOffset()这两个方法:
/****@param startX:开始滚动时候的x坐标*@param startY:开始滚动时候的y坐标*@param dx:水平方向上要滚动的距离*@param dy:竖直方向上要滚动的距离*@param duration:滚动持续的时间**/ public void startScroll(int startX, int startY, int dx, int dy, int duration) { mMode = SCROLL_MODE; mFinished = false; mDuration = duration; //初始化动画开始时间 mStartTime = AnimationUtils.currentAnimationTimeMillis(); //初始化滚动的起始位置坐标(mStartX,mStartY) mStartX = startX; mStartY = startY; //初始化滚动结束后的位置坐标(mFinalX,mFinalY) mFinalX = startX + dx; mFinalY = startY + dy; //初始化滚动的距离 mDeltaX = dx; mDeltaY = dy; mDurationReciprocal = 1.0f / (float) mDuration; }名字叫startScroll该方法并没有产生滚动,它的主要作用是初始化滚动的起始位置和结束的位置.即设定了如下信息:即由起始坐标(startX,startY)经过duration的时间滚动到了终点坐标(startX+dx,startY+dy);
下面在简单的说一下computeScrollOffset(),该方法如果返回true的话表明滚动还没有结束,反之表明滚动已经结束;同时通过该方法计算出了当前已经滚动的位置坐标(mCurrX,mCurrY),这两个位置变量可以通过getCurrX()、getCurrY()来获取到。
到此为止Scroller核心已经简单的过了一遍.。源码倒是不难理解,但是通读源码发现这个东西跟要滚动的View没有丝毫的联系,那么这个类我们要怎能使用呢?这正是本文即将说明的问题。
其实android学习的过程中,某些知识点自己写一个例子测试一下进行验证是最好不过的,比如下面我就准备拿我写的测试例子写一下:
点击页面中的ImageView,让该ImageView调用layout方法上下移动300个单位。这个功能很简单吧,直接调用如下代码就可以实现:
private int deltaX = 0;private int deltaY = 0; //点击 public void resetPosition(View v) {deltaX += 300;deltaY += 300;v.layout(deltaX,deltaY, v.getWidth()+deltaX, v.getHeight()+deltaY);}但是这个运行的结果是瞬间把图片移动到指定距离的位置,一点平滑过渡的效果都没有;那么如果用怎么样图片平缓的移动到制定的位置呢?Scroller当然可以实现这种效果
通过不断调用computeScrollOffset(),获取当前滚动到的水平/竖直的位置,调用layout方法不断设置layout方法参数的位置就可以了。所以简单的修改下上面的逻辑,点击ImageView事件的源码:
public void resetPosition(View v) {scroller.startScroll(v.getLeft(), v.getTop(), delta, delta,3000);sendMsg(v);}private void sendMsg(View v) {Message msg = Message.obtain();msg.obj = v;msg.arg1 = 0;mHandler.sendMessage(msg);}private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { if(scroller.computeScrollOffset()) {//滚动尚未结束 //获取已经滚动的位置 int currentX = scroller.getCurrX(); int currentY = scroller.getCurrY(); View v = (View)msg.obj; //修改ImageView的位置 v.layout(currentX,currentY, v.getWidth()+currentX, v.getHeight()+currentY); //发送消息,继续调用comeputeScrollOffset sendMsg(v); } }; };
上面的源码实现起来也很简单,如果没有停止滚动就不断发送消息,在handleMessage里面调用computeScrollOffset来判断是否结束滚动,没有结束的话就根据当前滚动的位置来设置layout ImageView的位置!!!
到此为止此博客就结束了,至于Scroller的一深入的用法以后遇到这方面的需求了,继续深入研究。demo下载链接点击此处下载
- View的滚动原理简单解析(二)
- View的滚动原理简单解析
- 读书笔记--View的工作原理(二)
- View的工作原理(二)
- View的工作原理(二)----View的工作流程
- 自定义view-----滚动的刻度尺(二)
- scroller view滚动的简单使用方法
- listView滚动view置顶的简单做法
- 自顶向下解析View的Measure原理(上)
- Android——View的工作原理(二)
- Picasso源码的简单解析(二)
- Struts2原理的简单解析
- View的工作原理(二)--从measure说View的测量流程
- View的工作原理(二)View的三大流程
- View的工作原理(二)之 View的工作流程
- ViewPager组合其他View的简单使用(二)
- 自定义view(二)view的绘制原理简介
- 得到view的信息以及 view绘制流程解析(二)
- Modernizr——为HTML5和CSS3而生!
- Qt浅谈之四十四动态显示日志(QGraphicsItem)
- SQL server学习笔记
- 百度地图定位
- 大型网站图片服务器架构的演进
- View的滚动原理简单解析(二)
- Windows安装Memcached
- Zoho People:多级审批很轻松
- Hibernate一级缓存
- Intent
- 架构设计的内容
- 9 款你必须知道的 Material Design 调色板
- 无聊时总结总结算法之09基数排序
- JavaScript之事件