说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
来源:互联网 发布:项羽跟虞姬 知乎 编辑:程序博客网 时间:2024/05/27 16:43
前面说了Layout最主要的职责就是负责item的布局和空间的分配,这一节我们继续来看看CellLayout的父亲控件Workspace。手机的桌面是由几个屏幕的,你可以任意滑动的。这个布局就是一个Workspace。Launcher的Workspace主要的职责就是处理多个屏幕之间的滑动和壁纸的添加。
这里先提下,我们知道DragLayer包含了Workspace,Workspace又包含了几个CellLayout,那么我们首先应该知道,它们是如何各司其职而互不影响的。这个就是Android中事件的传递机制。我们知道,一个应用中,整个的布局是一个树状,那么当用户的一个Touch操作,比如点击事件,是如何从最外层的父亲控件传递到具体的子空间中去的。这个就要归功于View的onInterceptTouchEvent和onTouchEvent两个方法了。这两个方法的返回值决定了一个Touch事件的传递时序。onInterceptTouchEvent,顾名思义,就是起到一个拦截的作用。这两个方法是如何决定事件的传递的呢?
1、如果用户执行一个ACTION_DOWN事件,当前View的onInterceptTouchEvent返回true,则该事件和后续的ACTION_MOVE和,ACTION_UP将不再传递到View的子控件,而是直接交由该View的onTouchEvent来处理。
2、如果上面onInterceptTouchEvent返回false,则该事件和后续的ACTION_UP,ACTION_MOVE将也会透过onInterceptTouchEvent,继而传递到子控件的onInterceptTouchEvent。
3、如果该View的onInterceptTouchEvent返回false,事件传递到目标View,然后目标View的onTouchEvent又返回了false,那么事件将继续传递到目标View的上一级的onTouchEvent。如果目标View的onTouchEvent方法返回了true,说明此事件已被处理了。
了解了Android中Touch事件的传递机制,也就很容易弄清楚DragLayer,Workspace和CellLayout是如何做到各司其职的了。下面,就让我们一起打入Workspace的内部。
一、处理多个屏幕的滑动
我们知道Workspace是由几个CellLayout横向平铺组成的,那么简单点,就是实际的布局超出了手机的屏幕,那么就需要滑动,需要一个Scroller对象来计算每次滑动后的坐标以及处理滑动的状态。而且下了Launcher的源码,你会发现,报了很多红叉,其大部分是因为mScollX和mScollY错误,这是因为这两个属性是不公开的,子类无法直接使用,所以我们在实现的时候这部分注意,取mScollX和mScrollY的时候,用getScrollX和getScrollY,给mScrollX和mScrollY赋新值的时候,调用scrollBy()或者scrollTo函数来执行。
1、让几个CellLayout平铺,由于每个CellLayout的大小是手机的一屏幕大小,所以,这里让其横向平铺就很简单了,直接在onLayout中调用每个CellLayout的layout方法进行布局,按顺序布局的时候,只需要控制好每个CellLayout的left和right就可以了。
2、如何处理屏幕的滑动,屏幕滑动,莫非就需要在ACTION_MOVE事件中处理。我们在文章的开头介绍了Android的事件拦截机制,那么我们想,要让滑动事件让Workspace处理,而不会干扰到CellLayout,自然要在onInterceptTouchEvent中做一些处理了。那我们先从onInterceptTouchEvent方法入手,在onInterceptTouchEvent方法中显眼的位置,我们就可以一眼发现如下代码:
同时在ruturn的时候,其返回的是:mTouchState != TOUCH_STATE_STOPED;这个就是说,如果当前正在滑动,则返回true,交给onTouchEvent事件来处理滑动逻辑。
那么,我们就再来看看onTouchEvent中对ACTION_MOVE事件的处理:
在这里,根据新的坐标位置,就算是向左还是向右滑动。同时处理滑动操作。那么,当我们停下的时候,它又是怎么做的呢?看ACTION_UP事件中的处理逻辑:
注意了,这里用VelocityTracker 计算了滑动的速度,因为,我们在滑动桌面的时候,应该注意到一个细节,当我们不是拖着桌面滑动,而是很快的滑动的时候,屏幕之间滑动到下一个屏幕的。这个就是通过VelocityTracker 计算滑动速度,如果滑动速度大于某个值,就直接滑动到下一个屏幕。具体的滑动到哪一个屏幕,是由方法snapToScreen处理的。那么我们就来看看这个好方法的逻辑:
在这个snapToScreen的方法中,逻辑很简单,主要就是调用了Scroller的startScroll方法,以当前滑动的位置和目标位置作为参数,启动滑动。但是,仅仅这样,这个方法起不到任何的效果,因为startScroll方法只是开始滑动,并不会不断的更新数据和处理滑动中的事情,这些事情是由computeScroll方法完成的。下面,我们再进入computeScroll方法来看看其逻辑:
到这里,整个屏幕为什么会滑动,这其中的逻辑处理,我想就基本清楚了。
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- 说说Android桌面(Launcher应用)背后的故事(九)——让我的桌面多姿多彩
- 说说Android桌面(Launcher应用)背后的故事(九)——让我的桌面多姿多彩
- 说说Android桌面(Launcher应用)背后的故事(九)——让我的桌面多姿多彩
- 说说Android桌面(Launcher应用)背后的故事(一)——揭开她神秘的面纱
- 说说Android桌面(Launcher应用)背后的故事(二)——应用程序的添加
- 说说Android桌面(Launcher应用)背后的故事(三)——CellLayout的秘密
- 说说Android桌面(Launcher应用)背后的故事(五)——桌面壁纸的添加
- 说说Android桌面(Launcher应用)背后的故事(二)——应用程序的添加
- 说说Android桌面(Launcher应用)背后的故事(一)——揭开她神秘的面纱
- 说说Android桌面(Launcher应用)背后的故事(一)——揭开她神秘的面纱
- 说说Android桌面(Launcher应用)背后的故事(二)——应用程序的添加
- 说说Android桌面(Launcher应用)背后的故事(三)——CellLayout的秘密
- 说说Android桌面(Launcher应用)背后的故事(五)——桌面壁纸的添加
- JS 中 && 和 || 区别与联系,
- (小技巧)Sql server查看sql语句的执行时间
- 通过btn传递两个实例对象
- astgo-官方功能更新日志
- WinForm maida player控件常用属性
- 说说Android桌面(Launcher应用)背后的故事(四)——揭秘Workspace
- for循环嵌套制作九九乘法表
- webpack入门(六)——html-webpack-plugin
- SQL Server 触发器
- iOS ReactiveCocoa
- 题目1125:大整数的因子
- OpenFileDialog打开多种类型的文件
- .Net与Oracle的数据库连接池(ConnectionPool)
- Eclipse智能提示及快捷键