接着上一篇文章,继续分析AllAPP列表界面。上一篇文章分析了所有应用列表的界面构成以及如何通过配置文件修改属性。今天主要是分析PagedViewWithDraggableItems类,因为在我们分析AppsCustomizePagedView之前,需要先了解PagedViewWithDraggableItems。这是因为他们是继承关系。我们先看看AppsCustomizePagedView的类继承关系。
![](http://www.apkbus.com/data/attachment/forum/201307/11/134754rsebniwee3k72wdy.jpg)
1、触摸拦截
从上面的类关系图我们可以看到,我们今天需要分析的PagedViewWithDraggableItems类是继承了PagedView类。PagedView我在第六篇文章里面已经做了详细分析。PagedView里面主要就是实现了界面滑动操作,PagedView把页面滑动的消息在onInterceptTouchEvent()里面拦截了,然后在onTouchEvent()里面进行滑动页面的处理。既然PagedViewWithDraggableItems也是继承PagedView,我们先看看PagedViewWithDraggableItems有关触摸事件的拦截和处理。
- //Edited by mythou
- //http://www.cnblogs.com/mythou/
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev)
- {
- if(OWL_DEBUG) Log.d(OWL, "enter- onInterceptTouchEvent ");
- handleTouchEvent(ev);
- return super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- if(OWL_DEBUG) Log.d(OWL, "enter- onTouchEvent ");
- handleTouchEvent(ev);
- return super.onTouchEvent(ev);
- }
复制代码
PagedViewWithDraggableItems的onInterceptTouchEvent和onTouchEvent处理都很简单,而且都调用了同一个处理方法。调用完handleTouchEvent(ev)方法后,会直接调用父类的相对应接口。父类的接口也就是PagedView的接口,这两个拦截触摸消息的回调方法,我们在上一篇文章已经做了很详细分析,这里不再多说。根据代码执行顺序,我们可以知道,界面会先调用PagedViewWithDraggableItems的onInterceptTouchEvent方法并且做了一些额外处理,然后才会调用PagedView的处理。下面我们看看PagedViewWithDraggableItems的handleTouchEvent方法做了什么事。 2、handleTouchEvent方法
- //Edited by mythou
- //http://www.cnblogs.com/mythou/
- private void handleTouchEvent(MotionEvent ev)
- {
- final int action = ev.getAction();
- if(OWL_DEBUG) Log.d(OWL, "handleTouchEvent action="+(action & MotionEvent.ACTION_MASK)+
- " mTouchState="+mTouchState+" mIsDragging="+mIsDragging+" mIsDragEnabled="+mIsDragEnabled);
- switch (action & MotionEvent.ACTION_MASK)
- {
- case MotionEvent.ACTION_DOWN: //按下事件处理
- cancelDragging();
- mIsDragEnabled = true;
- break;
- case MotionEvent.ACTION_MOVE: //进入滑动状态
- if (mTouchState != TOUCH_STATE_SCROLLING && !mIsDragging && mIsDragEnabled)
- {
- //根据是否进入滚动状态,判断是否需要拖曳按钮
- if(OWL_DEBUG) Log.d(OWL, "handleTouchEvent--->before drag ");
- determineDraggingStart(ev);
- }
- else
- {
- if(OWL_DEBUG) Log.d(OWL, "handleTouchEvent--->Not drag ");
- }
- break;
- }
- }
复制代码
从上面代码我们可以看到handleTouchEvent里面判断了两种触摸状态:ACTION_DOWN和ACTION_MOVE。在ACTION_DOWN的时候会清理有关拖动图标的标记。而在ACTION_MOVE的时候,会根据当前TouchState是不是滚动状态,如果不是,进入拖动图标操作。TouchState是根据PagedView里面的状态判断的,这个我们分析TouchState的时候已经分析过。下面我们看看代码调用流程,下面是我加了打印消息后,LogCat的消息:
![](http://www.apkbus.com/data/attachment/forum/201307/11/134755elxmuvn00wxfh76g.jpg)
上面是我结合PagedView类和PagedViewWithDraggableItems类对一次界面滑动的代码跟踪 ,我们可以看到系统先调用PagedViewWithDraggableItems的onInterceptTouchEvent然后依次调用上面分析的代码。需要注意的是上面LogCat高亮喊信息里面,会跑到handleTouchEvent的ACTION_MOVE,然后调用determineDraggingStart()方法。不过这里并不会调用PagedViewWithDraggableItems的determineDraggingStart()方法,而且调用了AppsCustomizedPagedView的方法,因为在AppsCustomizedPagedView里面把这个方法重写了。是一个空方法。
4、拖曳按钮 上面分析的流程是滑动界面执行的代码流程,下面我们看看如果你需要拖曳一个按钮,会怎么样。Android里面拖曳一个按钮,首先需要除非LongClick消息,也就是需要长按按钮才行。下面我们跟踪LogCat消息看看代码运行情况:
- //Edited by mythou
- //http://www.cnblogs.com/mythou/
- @Override
- public boolean onLongClick(View v)
- {
- if(OWL_DEBUG) Log.d(OWL, "onLongClick Enter");
-
- //下面有几种情况会取消长按触摸,不是触摸状态,正在动画过渡,离开了allAPP页面
- if (!v.isInTouchMode()) return false;
- // Return early if we are still animating the pages
- if (mNextPage != INVALID_PAGE) return false;
- // When we have exited all apps or are in transition, disregard long clicks
- if (!mLauncher.isAllAppsCustomizeOpen() ||
- mLauncher.getWorkspace().isSwitchingState()) return false;
-
- if(OWL_DEBUG) Log.d(OWL, "onLongClick beginDragging()");
- //调用开始拖曳的设置,里面会设置一些标记
- return beginDragging(v);
- }
复制代码
![](http://www.apkbus.com/data/attachment/forum/201307/11/134755nlf5z0z44c49152f.jpg)
PagedViewWithDraggableItems的onLongClick()方法,只是执行了简单的标记设置。到这里应该可以了解PagedViewWithDraggableItems主要的作用,因为Launcher里面很大一部分功能就是对于这种手势操作的处理,所以有必要认真分析这几个基类。为后面分析AppsCustomizedPagedView打好基础。