图标拖动
上篇文章简单讲述了图标的拖动流程,关于回调里的并没有介绍。(因为我也蒙蔽,哈哈哈,看着各种坐标、各种变量、头很大)but,在小编的不断努力
(注释掉代码看效果)下,逐渐有了一点点眉目。在这里和各位盆友分享一下。
由于是调试总结出来的文章,小编只能从可见的功能上给大家做一介绍。在此,非常抱歉没有一个好的功底来完全熟悉后来写。只能慢慢补充
如果有更详细的介绍的blog,欢迎留言告诉我,大家共同进步。
1、关于dropTarget.onDragOver( mDragObject );
当长按起桌面图标,移动时,经过空位置、其他图标、文件夹,都是workspace的onDragOver
从功能上看,分为1、拖动到另一个图标上创建一个个文件夹虚影;2、拖动到另一个图标附近挤走原本的图标
-
//获得拖动图标的视觉中心位置
-
mDragViewVisualCenter = getDragViewVisualCenter( d.x , d.y , d.xOffset , d.yOffset , d.dragView , mDragViewVisualCenter );
-
//拖动的时候也要判断当前位置Layout的是处于翻动的页面还是Hotseat中,确定mDragTargetLayout
-
// Test to see if we are over the hotseat otherwise just use the current page
-
if( mLauncher.getHotseat() !=
null && !isDragWidget( d ) )
-
{
-
if( isPointInSelfOverHotseat( d.x , d.y , r ) )
-
{
-
layout = mLauncher.getHotseat().getLayout();
-
}
-
}
-
if( layout ==
null )
-
{
-
layout = getCurrentDropLayout();
-
}
-
if( layout != mDragTargetLayout )
-
{
-
setCurrentDropLayout( layout );
-
setCurrentDragOverlappingLayout( layout );
-
}
//findNearestArea方法根据mDragViewVisualCenter先大致当前的落点 mTargetCell = findNearestArea( (int)mDragViewVisualCenter[0] , (int)mDragViewVisualCenter[1] , minSpanX , minSpanY , mDragTargetLayout , mTargetCell );
FolderCreationAlarmListener:文件夹创建动画监听。监听的处理都在onAlarm方法里。文件夹的预览图在Folder的onDraw里:
//管理文件夹反馈(修改mDragMode)。是否生成文件夹虚影,是否添加到文件夹,都是这里判断的 manageFolderFeedback( info , mDragTargetLayout , mTargetCell , targetCellDistance , dragOverView ); //落点位置是否被占用 boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied( (int)mDragViewVisualCenter[0] , (int)mDragViewVisualCenter[1] , item.getSpanX() , item.getSpanY() , child , mTargetCell ); if( !nearestDropOccupied ) { mDragTargetLayout.visualizeDropLocation( child , mDragOutline , (int)mDragViewVisualCenter[0] , (int)mDragViewVisualCenter[1] , mTargetCell[0] , mTargetCell[1] , item.getSpanX() , item.getSpanY() , false , d.dragView.getDragVisualizeOffset() , d.dragView.getDragRegion() ); } else if( ( mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER ) && !mReorderAlarm.alarmPending() && ( mLastReorderX != reorderX || mLastReorderY != reorderY ) ) {//位置被占用,把图标挤走,并且挤走的图标来回晃动逻辑在这里 // Otherwise, if we aren't adding to or creating a folder and there's no pending // reorder, then we schedule a reorder ReorderAlarmListener listener = new ReorderAlarmListener( mDragViewVisualCenter , minSpanX , minSpanY , item.getSpanX() , item.getSpanY() , d.dragView , child ); mReorderAlarm.setIOnAlarmListener( listener ); mReorderAlarm.setAlarm( REORDER_TIMEOUT ); } if( mDragMode == DRAG_MODE_CREATE_FOLDER || mDragMode == DRAG_MODE_ADD_TO_FOLDER || !nearestDropOccupied ) { if( mDragTargetLayout != null ) { mDragTargetLayout.revertTempState(); } }
int centerX = mTempLocation[0] + mCellWidth / 2; //文件夹预览图(一个图标覆盖到另一个图标或者文件夹上会生成文件夹预览图)的图标在绘制时的中心点的y坐标 int centerY = mTempLocation[1] + previewOffset / 2 + child.getPaddingTop() + grid.folderBackgroundOffset;//xiatian add note //桌面图标显示的样式(详见BaseDefaultConfig.java中的“ITEM_STYLE_XXX”)。//BubbleTextView重载方法“getPaddingTop” // Draw outer ring, if it exists if( FolderIcon.HAS_OUTER_RING ) { d = FolderRingAnimator.sSharedOuterRingDrawable;//文件夹预览图 width = (int)( fra.getOuterRingWidthSize() * getChildrenScale() ); height = (int)( fra.getOuterRingHeightSize() * getChildrenScale() ); canvas.save(); canvas.translate( centerX - width / 2 , centerY - height / 2 ); d.setBounds( 0 , 0 , width , height ); d.draw( canvas ); canvas.restore(); }
ReorderAlarmListener:重新排序动画监听。监听的处理都在onAlarm方法里。mDragTargetLayout.createArea(里,是把图标挤走和晃动的逻辑:
-
// If we're just testing for a possible location (MODE_ACCEPT_DROP), we don't bother
-
// committing anything or animating anything as we just want to determine if a solution
-
// exists
-
if( mode == MODE_DRAG_OVER || mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL )
-
{
-
if( !DESTRUCTIVE_REORDER )
-
{
-
copySolutionToTempState( finalSolution , dragView );
//记录被挤走的图标的位置
-
}
-
setItemPlacementDirty(
true );
-
animateItemsToSolution( finalSolution , dragView , mode == MODE_ON_DROP );
//把图标挤走
-
if( !DESTRUCTIVE_REORDER && ( mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL ) )
-
{
-
commitTempPlacement();
-
completeAndClearReorderHintAnimations();
-
setItemPlacementDirty(
false );
-
}
-
else
-
{
-
beginOrAdjustHintAnimations( finalSolution , dragView , REORDER_ANIMATION_DURATION );
//被挤走的图标晃啊晃的动画
-
}
-
}
2、关于dropTarget.onDragEnter( mDragObject );和mLastDropTarget.onDragExit( mDragObject );
当图标移动到(拖出)垃圾筐或者应用信息框上时,文字和图标变色功能介绍
回调在在DeleteDropTarget和InfoDropTarget里
卸载框:
public void onDragEnter( DragObject d ) { super.onDragEnter( d ); mCurrentDrawable.startTransition( mTransitionDuration ); setTextColor( mHoverColor );//当图标进入卸载框时,改变文字颜色 }
-
public void onDragExit(
-
DragObject d )
-
{
-
super.onDragExit( d );
-
if( !d.dragComplete )
-
{
-
mCurrentDrawable.resetTransition();
-
setTextColor( mOriginalTextColor );
//当图标拖出卸载框时,还原文字颜色
-
}
-
else
-
{
-
// Restore the hover color if we are deleting
-
d.dragView.setColor( mHoverColor );
-
}
-
}
应用信息框:
-
public void onDragEnter(
-
DragObject d )
-
{
-
super.onDragEnter( d );
-
mDrawable.startTransition( mTransitionDuration );
-
setTextColor( mHoverColor );
//当图标进入应用信息框时,改变文字颜色
-
}
-
public void onDragExit(
-
DragObject d )
-
{
-
super.onDragExit( d );
-
if( !d.dragComplete )
-
{
-
mDrawable.resetTransition();
-
setTextColor( mOriginalTextColor );
//当图标拖出应用信息框时,还原文字颜色
-
}
-
}
他们都是调用了父类的方法并且改变的文字的颜色。
父类onDragEnter:
-
public void onDragEnter(
-
DragObject d )
-
{
-
d.dragView.setColor( mHoverColor );
//当图标拖入时,修改图标颜色
-
}
-
public void onDragExit(
-
DragObject d )
-
{
-
d.dragView.setColor(
0 );
//当图标拖出时,修改图标颜色
-
}
以上就是长按 图标进入或者拖出时,颜色的变化功能。
尾注:
暂时就跟踪代码呆这里,如果有进展,会持续更新。