Launcher3 PageView滑动原理

本文转载自:http://www.fookwood.com/archives/955

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

PagedView是用来左右滑屏的,Workspace正是他的子类,这里的Page就是桌面上一页一页的内容。其实他和ViewPager差不多,连名字都近似,不过PagedView更自由更复杂一些。

代码这么多,这得分析到啥时候去呀。

先说下这个滑动的过程吧。如果你还不熟悉android的触摸事件控制流程,点击这里。然后打开eclipse一步一步跟踪代码。

首先看onInterceptTouchEvent方法,ACTION_DOWN事件下来之后,他会记录下当前坐标,相对于父亲的坐标等等,然后判断下是否还在滑动状态,如果没有的话,把mTouchState置为TOUCH_STATE_REST,所代表的意思是桌面现在还是静止的状态。然后onInterceptTouchEvent会返回false。为什么会返回false呢,为什么不直接返回true进行拦截呢?一是因为如果拦截掉了的话,就不会响应图标的点击事件了,二是滑动并不是从ACTION_DOWN开始的,而是滑动一段距离之后开始的,你可以在你的桌面上试一试,你的手指滑动了一段距离之后图标才开始移动。

那这个逻辑是在哪里判断的呢?ACTION_DOWN完了之后是ACTION_MOVE,我们看onInterceptTouchEvent之中对他是怎么进行处理的。可以看到ACTION_MOVE的处理只是调用了determineScrollingStart,顾名思义,他来决定是否进行滑动。这个方法里的逻辑还是很清楚的。

2014-07-09_20-41-13

这个代码的大致意思就是判断距离是否已经移动够了,如果移动够了,就会吧mTouchState设为TOUCH_STATE_SCROLLING,所代表的意思是”现在的状态是滑动”。并且执行pageBeginMoving,他会调用onPageBeginMoving,这个回调默认是空的,方便他的子类去重写,非常有用的。这里值得一提的是touchSlop这个变量,他是从ViewConfiguration.getScaledPagingTouchSlop()方法获取的,ViewConfiguration保存了一些使用view的过程中常见的距离大小方法等等。

一旦mTouchState被设为了 TOUCH_STATE_SCROLLING,那么PagedView的onInterceptTouchEvent对后续的ACTION_MOVE都会返回true,到onTouchEvent中去处理了。

ontouchevent

 

上图是对滑动过程中对ACTION_MOVE的处理。主要的内容就是判断滑动了多少距离,如果大于1的话,就通过scrollBy方法来滑动这么个距离,这里的scrollBy可是整个PagedView的第一次高潮,这里实质性的改变了距离,给用户留下滑动的感觉 。scrollBy实际上调用的是scrollTo方法,这个重写父类的scrollTo,做了一些额外的工作(比如滑到第一屏再往左滑的时候滑不动了,有一个反馈的效果)。

随着你手指的移动,以上操作在反复的执行。显示出来的效果就是图标在跟随者你的手移动,so easy?

接下来还有一个松手的操作,松手后会自动滑到当前屏或者下一屏。我们来看一下代码,onTouchEvent对于ACTION_UP事件的处理。这个时候分为两种情况,一种是快速甩动的时候,如果我们快速在屏幕上滑动一小段距离,松手后桌面会滑到下一页;第二种情况是页面滑动了40%以上速度不快的情况下松手后滑到下一屏。

妈蛋,这变量太多了,看晕我了。

松手后滑动的操作都是由一堆“snap”开头的方法完成的,而这些“snap”开头的方法,最终都会调用到下面这个方法:

snapto

这个里有个成员对象mScroller,他封装了一些滑动的操作,指明滑动的起始位置,滑动的距离和时间,mScroller会自己计算某个时间点上滑动的具体坐标,不用自己去算了,这个mScroller也可以设置各种Interpolator,mScroller的默认实现是ScrollInterpolator,自己定义的一个插值器,用来实现快达到位置的速度变化的效果。当然,你可以用这个mScroller来做一些自定义,比如说“回弹效果”(见小米桌面)。

那么谁来获取mScroller的值呢?pagedView重写了computeScroll方法,他会改变mScrollX和mScrollY,这些值控制的就是显示的内容。当滑动结束的时候调用pageEndMoving预示这滑动结束,如果子类重写了onPageEndMoving方法的话就会被调用到,可以和onPageBeginMoving配合使用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值