Launcher3 拖动图标笔记

本文主要记录了Launcher3拖动时的流程和代码记录,在桌面图标拖动时会引起图标的重排,拖动时受影响的图标在文中由item或cell来表示。

图标点击效果和摇动效果

mTouchFeedbackView为点击按下时图标表面一层透明灰色动画效果,这个动画效果在Celllayout中,在构造函数中addView加入,BubbleTextView 中 setStayPressed方法调用这个动画效果,在点击图标时呈现,下图就是我把Wallpaper改变成纯白色,更改动画位置,这样效果很明显。

点击图标动画

addView(mTouchFeedbackView, (int) (grid.cellWidthPx * 1.5), (int) (grid.cellHeightPx * 1.5));
addView(mShortcutsAndWidgets);

拖动时受影响的Item有一个摇动的(shake)动画,这个动画效果是通过ReorderPreviewAnimation和mShakeAnimators实现,受影响的item由ItemConfiguration管理,Celllayout-completeAndClearReorderPreviewAnimations方法播放动画,在适当时机调用。这个动画比较有意思,单纯的线性动画没有这种效果,看了代码才发现用到了贝塞尔曲线线性方程,这部分代码主要在Celllayout中。

图标的占位

Celllayout的boolean[][] mOccupied存储桌面图标布局中是否有图标占位,存在则为true,该对象在CellLayout的addViewToCellLayout方法赋值,这个方法在Workspace-addInScreen方法中调用,而桌面初始化时的bind过程会一直调用到这个方法。

图标拖动处理

DragController和DragLayer

DragLayer是Launcher3中处理拖动图标事件时自定义View,DragController的注释为:发起一个在一个View内或在几个View之间拖动事件的类。从名字可以看出这个类是一个调节者或控制者。

在DragLayer-onInterceptTouchEvent方法将事件给DragController-onInterceptTouchEvent方法处理。拖动图标的事件开始处理时,会一直调用到DragController-startDrag方法,此时,startDrag里将mDragging置为true,而DragController-onInterceptTouchEvent返回mDragging,此时截断事件传递,当前View处理触摸事件。类似的,DragLayer的onTouchEent方法也将事件给DragController的onTouchEent方法处理。

handleMoveEvent方法为处理触摸事件的主要方法,在handleMoveEvent方法中调用findDropTarget取的当前的具体的DropTarget对象,DragController中有一个mDropTargets链表,这个链表中在桌面的加载和操作会包含进来具体DropTarget对象,在Launcher3中,实现DropTarget类的有Folder和Workspace等,这个interface抽象了拖动时落点对象。DropTarget-isDropEnabled方法,表示当前这个落点View是否可以Drop,当该方法返回false时,显然是不能将拖动的Object放到这里来的。checkTouchMove方法检查拖动时的状态,根据拖动时DropTarget之间的关系调用DropTarget声明的onDrop,onDragEnter,onDragExit,onDragOver方法进行视图的演示,最后调用checkScrollState方法,这个方法主要是对拖动时的翻页进行判断处理。

DropTarget为Workspace的拖动处理

根据checkTouchMove方法,在Workspace中开始拖动图标时,图标开始时在Workspace中,此时DropTarget也为Workspace,所以刚开始时调用Workspace的onDragEnter方法,紧接着调用Workspace的onDragOver方法。而onDragExit方法的调用时机为拖动的Cell离开当前Target,当前Target变为mLastDropTarget,又没有进入一个有效的Target时。
Workspace的onDragEnter方法,这个方法比较简单,对Workspace的拖动时的涉及到的变量进行了初始化。

Workspace的onDragOver方法,在Workspace中有一个mDragViewVisualCenter变量,根据字面理解,这个变量是拖动对象的视觉中心位置,由getDragViewVisualCenter方法计算而来,在对拖动处理时多处使用,此外拖动的时候也要判断当前位置Layout的是处于翻动的页面还是Hotseat中,确定mDragTargetLayout。接着findNearestArea方法根据mDragViewVisualCenter先大致当前的落点,findNearestArea方法会调用到Celllayout的findNearestArea方法,根据不同情况在调用的过程中会分别考虑和不考虑当前页面的其他item的占用情况。确定了可能的落点后首先对Folder情况进行处理,分别为新建和加入已有的Folder两种,然后是落点已经被其他的Item占据的情况,这里调用performReorder方法处理,这个方法相当长,拖动过程中和结束拖动放下时的onDrag方法中都会调用这个方法,拖动过程中图标的重排效果就是在此方法中实现的。Workspace的onDragExit方法,根据上面onDragExit的调用时机,这里主要确定拖动图标离开有效DragTarget时最后的落点。

根据DragController的onTouchEent方法,触摸事件为MotionEvent.ACTION_UP时,拖动事件结束,这时有两种可能:当满足快速向上扔时,删除拖动的item,isFlingingToDelete方法判断条件是否满足。如果不满足扔的条件,调用drop方法,drop方法调用DropTarget的acceptDrop方法,判断该Drop事件是否发生,依此调用DropTarget的onDrop方法。

Workspace-onDrop()流程,方法参数为DropTarget-DragObject对象,首先计算拖动View的视觉中心mDragViewVisualCenter,dropTargetLayout为Drop的Celllayout对象,下一步判断当前是否在Hotseat上,求出相对于dropTargetLayout的视觉中心坐标。如果DragObject-dragSource!=Worspace,转而调用onDropExternal(),否则继续处理onDrop()的内容。接着调用findNearestArea方法球drop的xy的值,Workspace-findNearestAr

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值