Launcher长按拖拽流程(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a396604593/article/details/52872911

图标拖动

上篇文章简单讲述了图标的拖动流程,关于回调里的并没有介绍。(因为我也蒙蔽,哈哈哈,看着各种坐标、各种变量、头很大)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 );	
//管理文件夹反馈(修改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();
	}
}
FolderCreationAlarmListener:文件夹创建动画监听。监听的处理都在onAlarm方法里。文件夹的预览图在Folder的onDraw里:

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 );//当图标拖出时,修改图标颜色
}
以上就是长按 图标进入或者拖出时,颜色的变化功能。

尾注:

暂时就跟踪代码呆这里,如果有进展,会持续更新。

猜你喜欢

转载自blog.csdn.net/a396604593/article/details/52872911
今日推荐