Launcher长按拖拽流程(三)长按松手简述

图标拖拽之松手逻辑

前两节简单概述了一下图标的拖动流程,本章来介绍一下松手之后的一些界面逻辑处理。
从功能上可以分为一下几种情况:
1、松手后,卸载应用,删除桌面图标
2、松手后,进入应用信息界面
3、松手后,形成文件夹
4、松手后,放入文件夹内
5、松手后,放在桌面空位置
第一章讲过,松手后的逻辑处理是在DragController类的onTouchEvent方法,
MotionEvent.ACTION_UP:中调用drop( dragLayerX , dragLayerY );
private void drop(
		float x ,
		float y )
{
	final int[] coordinates = mCoordinatesTemp;
	final DropTarget dropTarget = findDropTarget( (int)x , (int)y , coordinates );//根据坐标获取当前的dropTarget
	mDragObject.x = coordinates[0];
	mDragObject.y = coordinates[1];
	boolean accepted = false;
	if( dropTarget != null )
	{
		mDragObject.dragComplete = true;
		dropTarget.onDragExit( mDragObject );//先退出dropTarget
		if( dropTarget.acceptDrop( mDragObject ) )//判断是否可以放下
		{
			dropTarget.onDrop( mDragObject );//放下之后的逻辑
			accepted = true;
		}
	}
	mDragObject.dragSource.onDropCompleted( (View)dropTarget , mDragObject , false , accepted );//完全放下后的处理
}

1、松手后进入应用信息界面的逻辑

if( dropTarget.acceptDrop( mDragObject ) )//判断是否可以放下,回调到InfoDropTarget:

@Override
public boolean acceptDrop(
		DragObject d )
{
	// acceptDrop is called just before onDrop. We do the work here, rather than
	// in onDrop, because it allows us to reject the drop (by returning false)
	// so that the object being dragged isn't removed from the drag source.
	ComponentName componentName = null;
	if( d.dragInfo instanceof AppInfo )//主菜单里的图标
	{
		componentName = ( (AppInfo)d.dragInfo ).getComponentName();
	}
	else if( d.dragInfo instanceof ShortcutInfo )//桌面应用
	{
		componentName = ( (ShortcutInfo)d.dragInfo ).getIntent().getComponent();
	}
	else if( d.dragInfo instanceof PendingAddItemInfo )//小部件
	{
		componentName = ( (PendingAddItemInfo)d.dragInfo ).getComponentName();
	}
	if( componentName != null )
	{
		mLauncher.startApplicationDetailsActivity( componentName );//启动应用信息界面
	}
	// There is no post-drop animation, so clean up the DragView now
	d.deferDragViewCleanupPostAnimation = false;
	return false;
}
启动应用信息界面:

void startApplicationDetailsActivity(
		ComponentName componentName )
{
	String packageName = componentName.getPackageName();
	Intent intent = new Intent( Settings.ACTION_APPLICATION_DETAILS_SETTINGS , Uri.fromParts( "package" , packageName , null ) );
	intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS );
	startActivitySafely( null , intent , "startApplicationDetailsActivity" );
}

2、松手后,卸载应用,删除桌面图标

if( dropTarget.acceptDrop( mDragObject ) )//判断是否可以放下,回调到DeleteDropTarget:

这个方法里判断各种item类型并返回是否可以卸载。具体的卸载代码当然就在if里面的代码块dropTarget.onDrop( mDragObject );回调中。

卸载完应用后,再调用mDragObject.dragSource.onDropCompleted( (View)dropTarget , mDragObject , false , accepted );处理图标的删除逻辑等等。

3、松手后,形成文件夹/放入文件夹里/放在桌面空白处

这三种情况下,都是长按桌面的图标后的操作,所以他们有共同的dropTarget和mDragObject.dragSource(都是workspace)。对应的逻辑处理就再workspace对应的回调中进行。

略略略,写不下去了,以后有问题时再跟踪代码。,。,。

要去做别的项目咯,launcher笔记暂时写到这里

仿Launcher的GridView拖动是一个按GridView的item,然后将其拖拽其他item上面,使得GridView的item发生交换,比较典型的就是我们的Launcher,网上有很多关于GridView的拖动的Demo,但是大部分都是相同的,而且存在一些Bug,而且大部分都是点击GridView的item然后进行拖动,或者item之间不进行实时交换,今天给大家更加详细的介绍GridView拖拽,并且将Demo做的更完美。   实现思路: 1、根据手指按下的X,Y坐标来获取我们在GridView上面点击的item 2、手指按下的时候使用Handler和Runnable来实现一个定时器,假如定时时间为1000毫秒,在1000毫秒内,如果手指抬起了移除定时器,没有抬起并且手指点击在GridView的item所在的区域,则表示我们按了GridView的item 3、如果我们按了item则隐藏item,然后使用WindowManager来添加一个item的镜像在屏幕用来代替刚刚隐藏的item 4、当我们手指在屏幕移动的时候,更新item镜像的位置,然后在根据我们移动的X,Y的坐标来获取移动到GridView的哪一个位置 5、到GridView的item过多的时候,可能一屏幕显示不完,我们手指拖动item镜像到屏幕下方,要触发GridView想上滚动,同理,当我们手指拖动item镜像到屏幕上面,触发GridView向下滚动 6、GridView交换数据,刷新界面,移除item的镜像 本例子来自于CSND xiaanming的博客,详细的源码分析已经帮大家离线成pdf文档了。   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值