讲解了各类特殊的操作,不能忘记最常见的操作,把图标放到桌面上。
workspace的droptarget,首先是onDragEnter,从folder或者buttonTargetBar进入workspace。比如先从workspace拖动到buttonTargetBar,然后再回到workspace里。最后回到workspace里面的时候,就会触发workspace的onDragEnter。其中有个方法setDropLayoutForDragObject。其细节是,从buttonTargetBar拖动回来,有可能是拖动到worksapce的边上会触发翻页的边上,这样就要求翻一页。
public void onDragEnter(DragObject d) {
if (ENFORCE_DRAG_EVENT_ORDER) {
enforceDragParity("onDragEnter", 1, 1);
}
mCreateUserFolderOnDrop = false;
mAddToExistingFolderOnDrop = false;
mDropToLayout = null;
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
setDropLayoutForDragObject(d, mDragViewVisualCenter[0], mDragViewVisualCenter[1]);
}
在workspace里面拖动需要做的事情就多了:
public void onDragOver(DragObject d) {
// Skip drag over events while we are dragging over side pages
if (!transitionStateShouldAllowDrop()) return;
//首先是确认是否拖了明确的对象,检查iteminfo,因为后续的操作一定会用到item信息
ItemInfo item = d.dragInfo;
if (item == null) {
if (ProviderConfig.IS_DOGFOOD_BUILD) {
throw new NullPointerException("DragObject has null info");
}
return;
}
// 确认落脚点之前,先确认手指的位置,而后确定落脚点,在落脚点会有outline提示
if (item.spanX < 0 || item.spanY < 0) throw new RuntimeException("Improper spans found");
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
final View child = (mDragInfo == null) ? null : mDragInfo.cell;
if (setDropLayoutForDragObject(d, mDragViewVisualCenter[0], mDragViewVisualCenter[1])) {
if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
mSpringLoadedDragController.cancel();
} else {
mSpringLoadedDragController.setAlarm(mDragTargetLayout);
}
}
//还是确认落脚点,要分清楚是落在workspace还是hotseat
if (mDragTargetLayout != null) {
// We want the point to be mapped to the dragTarget.
if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
} else {
mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter);
}
//确认好落脚点之后,确认落脚需要的范围,一般是1x1。Widget则可能很大
int minSpanX = item.spanX;
int minSpanY = item.spanY;
if (item.minSpanX > 0 && item.minSpanY > 0) {
minSpanX = item.minSpanX;
minSpanY = item.minSpanY;
}
//寻找真实落脚点,有可能是没有落脚点的。比如将widget拖到hotseat上,但是hotseat不解释widget,此时算是没有落脚点。
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
(int) mDragViewVisualCenter[1], minSpanX, minSpanY,
mDragTargetLayout, mTargetCell);
int reorderX = mTargetCell[0];
int reorderY = mTargetCell[1];
setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]);
float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
manageFolderFeedback(mDragTargetLayout, mTargetCell, targetCellDistance, d);
//确认落脚点是否有其他东西在。将icon拖到widget的位置,则发现该地方由widget了。
但是,如果把icon拖到folder,则触发workspace的dragExit和folder的dragEnter。
boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int)
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
item.spanY, child, mTargetCell);
//如果有落脚点,那就绘制落脚点提示
if (!nearestDropOccupied) {
mDragTargetLayout.visualizeDropLocation(child, mOutlineProvider,
mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false, d);
&

本文详细剖析了Android Launcher 8.0中,用户如何将应用图标拖拽到桌面的过程。从onDragEnter、onDragOver到onDrop,逐一解释了每个阶段的工作原理,包括落脚点确认、动画效果、图标位置调整以及数据库更新等关键步骤。通过这些操作,理解了Launcher如何处理用户拖放操作并确保图标准确放置到桌面。
最低0.47元/天 解锁文章
1019

被折叠的 条评论
为什么被折叠?



