接着上一篇文章,继续分析AllAPP列表界面。上一篇文章分析了所有应用列表的界面构成以及如何通过配置文件修改属性。今天主要是分析PagedViewWithDraggableItems类,因为在我们分析AppsCustomizePagedView之前,需要先了解PagedViewWithDraggableItems。这是因为他们是继承关系。我们先看看AppsCustomizePagedView的类继承关系。(以后博客的图片都会加上水印,因为发现很多转载文章的人把所有作者信息都删除了,鄙视这种行为 ╭∩╮(︶︿︶)╭∩╮)

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的消息:

  上面是我结合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);
}

  PagedViewWithDraggableItems的onLongClick()方法,只是执行了简单的标记设置。到这里应该可以了解PagedViewWithDraggableItems主要的作用,因为Launcher里面很大一部分功能就是对于这种手势操作的处理,所以有必要认真分析这几个基类。为后面分析AppsCustomizedPagedView打好基础。

Launcher分析系列文章:

Android Launcher分析和修改1——Launcher默认界面配置(default_workspace)

Android Launcher分析和修改2——Icon修改、界面布局调整、壁纸设置

Android Launcher分析和修改3——Launcher启动和初始化

Android Launcher分析和修改4——初始化加载数据

Android Launcher分析和修改5——HotSeat分析

Android Launcher分析和修改6——页面滑动(PagedView)

Android Launcher分析和修改7——AllApp全部应用列表(AppsCustomizeTabHost)

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3183081.html 

Android Launcher分析和修改8——AllAPP界面拖拽元素(PagedViewWithDraggableItems)的更多相关文章

  1. Android Launcher分析和修改7——AllApp全部应用列表(AppsCustomizeTabHost)

    今天主要是分析一下Launcher里面的所有应用列表.Android4.0 Launcher的所有应用列表跟2.X比较大的区别就是多了Widget的显示.下面会详细分析Launcher里面有关所有应用 ...

  2. Android Launcher分析和修改13——实现Launcher编辑模式(1) 壁纸更换

    已经很久没更新Launcher系列文章,今天不分析源码,讲讲如何在Launcher里面添加桌面设置的功能.目前很多第三方Launcher或者定制Rom都有简单易用的桌面设置功能.例如小米MIUI的La ...

  3. Android Launcher分析和修改9——Launcher启动APP流程

    本来想分析AppsCustomizePagedView类,不过今天突然接到一个临时任务.客户反馈说机器界面的图标很难点击启动程序,经常点击了没有反应,Boss说要优先解决这问题.没办法,只能看看是怎么 ...

  4. Android Launcher分析和修改10——HotSeat深入进阶

    前面已经写过Hotseat分析的文章,主要是讲解如何在Launcher里面配置以及修改Hotseat的参数.今天主要是讲解一下如何在Hotseat里面的Item显示名称.这个小问题昨天折腾了半天,最后 ...

  5. Android Launcher分析和修改11——自定义分页指示器(paged_view_indicator)

    Android4.0的Launcher自带了一个简单的分页指示器,就是Hotseat上面那个线段,这个本质上是一个ImageView利用.9.png图片做,效果实在是不太美观,用测试人员的话,太丑了. ...

  6. Android Launcher分析和修改12——Widget列表信息收集

    很久没写Launcher分析的文章,最近实在太忙.今天七夕本来是想陪女朋友逛街 ,碰巧打台风呆在家里,就继续写一篇文章.今天主要是讲一下Launcher里面的Widget列表,这方面信息比较多,今天重 ...

  7. Android Launcher分析和修改3——Launcher启动和初始化

    前面两篇文章都是写有关Launcher配置文件的修改,代码方面涉及不多,今天开始进入Launcher代码分析. 我们开机启动Launcher,Launcher是由Activity Manager启动的 ...

  8. Android Launcher分析和修改4——初始化加载数据

    上面一篇文章说了Launcher是如何被启动的,Launcher启动的过程主要是加载界面数据然后显示出来, 界面数据都是系统APP有关的数据,都是从Launcher的数据库读取,下面我们详细分析Lau ...

  9. Android Launcher分析和修改5——HotSeat分析

    今天主要是分析一下Launcher里面的快捷方式导航条——HotSeat,一般我们使用手机底下都会有这个导航条,但是如果4.0的Launcher放到平板电脑里面运行,默认是没有HotSeat的,刚好我 ...

随机推荐

  1. SpringMVC框架09——@ResponseBody的用法详解

    @ResponseBody可以标注在方法上也可以标注在类上面.简单来说,当标注在方法上时,该方法的返回结果直接转成JSON格式:当标注在类上时,该类中的所有方法的返回结果都转换成JSON格式. 代码示 ...

  2. 多线程里面this.getName()和currentThread.getName()有什么区别

    public class hello extends Thread { public hello(){ System.out.println("Thread.currentThread(). ...

  3. 20172302《程序设计与数据结构》实验四Android程序设计实验报告

    课程:<程序设计与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年5月30日 必修/选修: 必修 1.实验内容 (1)And ...

  4. 在Springboot2.0项目中使用Druid配置多数据源

    在Springboot出现之前配置数据源以及相关的事物,缓存等内容一直是个繁琐的工作,但是Springboot出现后这些基本都可以靠默认配置搞定,就变得很轻松了.这就是现在推崇模板>配置的原因, ...

  5. .NetCore中EFCore for MySql整理(三)之Pomelo.EntityFrameworkCore.MySql

    一.Pomelo.EntityFrameworkCore.MySql简介 Git源代码地址:https://github.com/PomeloFoundation/Pomelo.EntityFrame ...

  6. windows php7 安装 mongodb 扩展

    1. 打开phpinfo 查看 nts(非线程) 还是 ts (线程),然后查看操作位数 注: 86 等于 32 位 2. 下载对应的版本的php_mongodb.dll 文件下载链接: pecl m ...

  7. shell中函数返回值

    1.前言 快半年没有写博客了,荒废了很久,工作中的杂事太多,自己越来越懒了.为了鞭策自己成长,还是要坚持写写博客,记录自己的成长. 2.shell函数介绍 语法: [ function ] funna ...

  8. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  9. 怎么重置mysql的自增列AUTO_INCREMENT初时值

    重置 MySQL 自增列 AUTO_INCREMENT 初时值 注意, 使用以下任意方法都会将现有数据删除. 方法一: delete from tb1; ALTER TABLE tbl AUTO_IN ...

  10. mock以及特殊场景下对mock数据的处理

    一.为什么要mock 工作中遇到以下问题,我们可以使用mock解决: 无法控制第三方系统某接口的返回,返回的数据不满足要求 某依赖系统还未开发完成,就需要对被测系统进行测试 有些系统不支持重复请求,或 ...