100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android开发者指南-用户界面-拖放-Drag and Drop[原创译文]

Android开发者指南-用户界面-拖放-Drag and Drop[原创译文]

时间:2022-06-30 17:00:31

相关推荐

Android开发者指南-用户界面-拖放-Drag and Drop[原创译文]

英文原文:/guide/topics/ui/drag-drop.html

版本:Android 4.0 r1

译者注:黄色底色为未决译文

快速查看允许用户在Activity layout范围内用图形化的手势来转移数据可用于转移数据之外的其它用途只在同一应用程序内有效需要API 11.在本文中概述拖放过程拖动事件侦听器及回调方法拖动事件拖动阴影拖放操作的设计开始拖动响应拖动开始事件拖动过程中的事件处理响应放下事件响应拖动结束事件响应拖动事件的示例关键类ViewOnLongClickListenerOnDragListenerDragEventDragShadowBuilderClipDataClipDescription相关示例Honeycomb GalleryApi Demos中的DragAndDropDemo.java和DraggableDot.java参阅Content ProvidersInput Events

利用Android的拖/放框架,你可以让用户用图形化的拖放手势把一个View中的数据移到当前layout内的另一个View中去。 拖放框架包括拖动事件类、拖动侦听器,以及helper方法和类。

虽然此框架主要是为转移数据而设计的,但你可以将它用于其它UI action。比如,你可以创建一个混合颜色的应用,用户可以把不同颜色的图标通过拖放叠在一起。 不过,本文描述的是转移数据这部分内容。

概述

当用户触摸出某个拖动数据的手势,即启动了拖放操作。作为响应,你的应用程序应通知系统拖动已开始。系统将回调你的应用程序,以获取拖动数据所显示的图像。 当用户手指在当前layout上方拖动这个图像(一个“拖动阴影”)时,系统会把拖动事件发送给拖动事件侦听器对象、layout内View对象关联的拖动事件回调方法。一旦用户放开这个拖动阴影,系统就会终止拖动操作。

你可以从View.OnDragListener类创建一个拖动事件侦听器对象(“listener”)。利用View对象的setOnDragListener()方法,可为View设置拖动事件侦听器对象。View对象还有一个onDragEvent()回调方法。这两个方法的详细信息都在拖动事件侦听器和回调方法一节中描述。

注意:为了简化起见,下文中把接收拖动事件的程序都叫做“拖动事件监听器”,尽管实际上它可能是个回调方法。

当你开始拖动时,要向系统调用传入两类信息:要转移的数据和描述这些数据的元数据。在拖动过程中,系统会把拖动事件发送给拖动事件侦听器或layout中所有View的回调方法。 此侦听器或回调方法可以利用元数据来确定是否在放下后接受数据。 如果用户在某个View对象上放下数据,并且该View对象的侦听器或回调方法之前已经通知系统愿意接受数据,则系统会把数据发送给侦听器或拖动事件中的回调方法。

通过调用startDrag()方法,你的应用程序可以通知系统开始拖动。这将通知系统开始发送拖动事件。此方法中还负责发送所拖动的数据。

你可以调用任何当前layout内已关联的View的startDrag()。系统用View对象来获得layout的全局设置参数。

当你的应用程序完成startDrag()调用后,剩下的步骤就是使用系统发送给当前layout中View对象的事件了。

拖/放过程

拖放过程有四个基本步骤或状态:

启动Started为了响应用户开始拖动的手势,你的应用程序应调用startDrag()来通知系统。startDrag()的参数需要指定所拖动的数据、元数据和绘制拖动阴影的回调方法。

作为响应,系统首先通过回调应用程序来获取拖动阴影。然后在设备上显示这个阴影。

下一步,系统会把一个带有action类型ACTION_DRAG_STARTED的拖动事件发送给当前layout中所有View对象的拖动事件侦听器。 为了能继续接收拖动事件,包括可能发生的放下事件,拖动事件侦听器必须返回true。 这会向系统注册侦听器。只有注册过的侦听器才能连续接收拖动事件。这时,侦听器还可以改变所属View对象的外观,以便显示出该侦听器可以接受放下事件。

如果拖动事件侦听器返回false,则在系统发送带有action类型ACTION_DRAG_ENDED的拖动事件之前,它就再不会收到当前操作的拖动事件了。 通过返回false,侦听器通知系统,它对此拖动操作不感兴趣,并且不愿意接受拖动的数据。

保持Continuing表示用户保持拖动状态。当拖动阴影与View对象的屏幕边界相交时,系统会发送一个或多个拖动事件给View对象的拖动事件侦听器(如果已经注册同意接收事件)。 作为对事件的响应,侦听器可以选择改变View对象的外观。比如,如果事件表明拖动阴影已经进入了View的边界(action类型ACTION_DRAG_ENTERED),侦听器可以让View高亮显示。放下Dropped表示用户在某个可接受数据的View的屏幕边界内释放了拖动阴影。系统会向View对象的侦听器发送一个带有action类型ACTION_DROP的拖动事件。拖动事件中包含了开始拖动时由startDrag()传给系统的数据。如果接受放下事件执行成功,侦听器应该向系统返回布尔值true。

记住,只有View的侦听器已注册接收拖动事件了,用户在此View边界内放下拖动阴影才会发生这一步。如果用户是在其它情况下释放拖动阴影,则不会发送ACTION_DROP拖动事件。

结束Ended用户释放了拖动阴影,系统也已发出(必要时)带有action类型ACTION_DROP拖动事件之后,系统会发出一个带action类型ACTION_DRAG_ENDED拖动事件,用以表明拖动操作已经结束。无论用户在何处释放拖动阴影,这一步都会发生。 此事件会发送给所有注册接收拖动事件的侦听器,即使侦听器已收到过了ACTION_DROP事件也一样。

拖放操作的设计一节中还会详细说明这四个步骤。

拖动事件侦听器及回调方法

一个View可以通过实现一个View.OnDragListener或者实现其onDragEvent(DragEvent)回调方法来接收拖动事件。当系统调用此方法或侦听器时,会传入一个DragEvent对象。

在绝大多数场合,你都会更愿意使用侦听器。当进行用户界面设计时,你通常不会建立View类的子类,可是要使用回调方法你就只能这么做,因为你要重写这个回调方法。 相比之下,你可以实现一个侦听器类,并把它用于多个不同的View对象。你也可以把侦听器实现为匿名的内嵌类。 要设置View对象的侦听器,请调用setOnDragListener()。

你可以同时对View对象使用侦听器和回调方法。这时,系统会首先调用侦听器。只有侦听器返回false时,系统才会再去调用回调方法。

onDragEvent(DragEvent)方法和View.OnDragListener的混合使用,与混用onTouchEvent()和触摸事件的View.OnTouchListener的效果类似。

拖动事件

系统以DragEvent对象的格式送出一个拖动事件。此对象包含了一个action类型,用于告诉侦听器拖放过程中发生的事件。根据action类型的不同,此对象中还包含了其它一些数据。

要获取action类型,侦听器调用getAction()即可。共有六种可能的类型,都在DragEvent类中用常量定义,已在表 1中列出。

DragEvent对象还包含了应用程序在startDrag()调用中提交给系统的数据。某些数据仅针对特定action类型才会有。 每种action对应的可用数据都列在了table 2中。表中还详细说明了拖放操作的设计一节中可用的事件。

表 1.DragEvent action type

表 2.action 类型对应的可用 DragEvent 数据

getAction()、describeContents()、writeToParcel()和toString()方法总是返回可用数据。

如果不包含某个action类型可用的数据,此方法会返回null或0,视结果类型而定。

拖动阴影

在拖放操作的过程中,系统会显示一个用户所拖动部分的图像。对于数据转移而言,这个图像代表了要拖动的数据。 对于其它操作,这个图像代表了被拖动的东西。

此图像叫做拖动阴影(drag shadow)。你可以用View.DragShadowBuilder来创建它,并在用startDrag()开始拖动时把它传给系统。 调用startDrag()后,系统会执行你在View.DragShadowBuilder中定义的回调方法来获取一个拖动阴影。

View.DragShadowBuilder类包含两个构造方法:

View.DragShadowBuilder(View)这个构造方法可接受你的应用程序中的任一View对象。它会在View.DragShadowBuilder对象中保存View对象,因此构造拖动阴影时你可以在执行回调方法中访问到该View。 这样就不一定要记住用户选中并开始拖动操作的View了(如果有的话)。

如果使用了本构造方法,你就不必扩展View.DragShadowBuilder及重写其方法。默认情况下,你会得到一个与参数中的View外观相同的拖动阴影,并且以用户触摸点为中心来显示。

View.DragShadowBuilder()如果你使用了本构造方法,则View.DragShadowBuilder对象中不存在View对象(对应的字段值为null)。 如果使用了本构造方法,且未扩展View.DragShadowBuilder并重写其方法,那么你将得到一个不可见的拖动阴影。且系统不会报错。

View.DragShadowBuilder类有两个方法:

onProvideShadowMetrics()当你调用了startDrag()之后,系统马上会调用本方法。可用于向系统发送拖动阴影的大小和触摸点坐标。本方法有两个参数:dimensions一个Point对象。其中的x和y对应了拖动阴影的宽和高。touch_point一个Point对象。触摸点是指用户手指在拖动过程中所触及的点在拖动阴影中的相对位置。X坐标用x表示,Y坐标用y表示。onDrawShadow()在调用onProvideShadowMetrics()之后,系统会立即调用onDrawShadow(),用于获取拖动阴影。本方法有一个参数,即一个Canvas对象,系统根据你在onProvideShadowMetrics()中给出的参数来构建它,并将在这个Canvas上绘制拖动阴影。

为了提高性能,你应该让拖动阴影尽可能小一些。对于单个目标,也许你该使用图标。如果选中了多个目标,也许你该把多个图标堆叠起来显示,而不是把整个图像显示在屏幕上。

拖放操作的设计

这一节分步展示了如何开始拖动、在拖动过程中响应事件、响应放下事件、结束拖放操作等内容。

开始拖动

用户用拖动手势来开始拖动,通常是在View对象上进行一个长按操作。在事件响应中,你应该进行:

必须创建用于移动数据的ClipData和ClipData.Item。在ClipData对象中,需要给出存放元数据的ClipDescription对象。对于不用于转移数据的拖放操作,你可能要用null来取代实际的对象。

比如,以下代码片段展示了如何响应ImageView上的长按操作,创建一个ClipData对象,其中包含了ImageView的tag或label。 然后,再下一段代码展示了如何重写View.DragShadowBuilder中的方法:

[java]view plaincopyprint? //创建一个字符串,用于ImageViewlabelprivatestaticfinalStringIMAGEVIEW_TAG="iconbitmap"//创建一个新的ImageViewImageViewimageView=newImageView(this);//用某个图标(在其它地方定义)的位图设置ImageView位图图像imageView.setImageBitmap(mIconBitmap);//设置tagimageView.setTag(IMAGEVIEW_TAG);...//把一个匿名侦听器对象设为ImageView的长按操作侦听器//侦听器实现了OnLongClickListener接口imageView.setOnLongClickListener(newView.OnLongClickListener(){//定义接口的方法,长按View时会被调用到publicbooleanonLongClick(Viewv){//新建一个ClipData//这用两步即可完成,//ClipData.newPlainText()方法可以很方便地一步完成一个纯文本ClipData的创建工作//用ImageView对象的tag创建一个新的ClipData.ItemClipData.Itemitem=newClipData.Item(v.getTag());//新建一个ClipData,用已有的tag作为label,纯文本MIME类型。//这会在ClipData中新建一个ClipDescription对象,//并把它的MIME类型一栏设为"text/plain"。ClipDatadragData=newClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);//实例化dragshadowbuilder.View.DrawShadowBuildermyShadow=newMyDragShadowBuilder(imageView);//开始拖动v.startDrag(dragData,//要拖动的数据myShadow,//dragshadowbuildernull,//不需要用到本地数据0//标志位(目前未启用,设为0));}}

// 创建一个字符串,用于ImageView labelprivate static final String IMAGEVIEW_TAG = "icon bitmap"// 创建一个新的ImageViewImageView imageView = new ImageView(this);// 用某个图标(在其它地方定义)的位图设置ImageView位图图像imageView.setImageBitmap(mIconBitmap);// 设置tagimageView.setTag(IMAGEVIEW_TAG);...// 把一个匿名侦听器对象设为ImageView的长按操作侦听器// 侦听器实现了OnLongClickListener接口imageView.setOnLongClickListener(new View.OnLongClickListener() {// 定义接口的方法,长按View时会被调用到public boolean onLongClick(View v) {// 新建一个ClipData// 这用两步即可完成,// ClipData.newPlainText()方法可以很方便地一步完成一个纯文本ClipData的创建工作// 用ImageView对象的tag创建一个新的ClipData.ItemClipData.Item item = new ClipData.Item(v.getTag());// 新建一个ClipData,用已有的tag作为label,纯文本MIME类型。// 这会在ClipData中新建一个ClipDescription对象,// 并把它的MIME类型一栏设为"text/plain"。ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);// 实例化drag shadow builder.View.DrawShadowBuilder myShadow = new MyDragShadowBuilder(imageView);// 开始拖动v.startDrag(dragData, // 要拖动的数据myShadow, // drag shadow buildernull,// 不需要用到本地数据0// 标志位(目前未启用,设为0));}}

以下代码段定义了myDragShadowBuilder为TextView创建一个拖动阴影,显示为一个灰色的小方框:[java]view plaincopyprint? privatestaticclassMyDragShadowBuilderextendsView.DragShadowBuilder{//拖动阴影图像,定义为一个drawableprivatestaticDrawableshadow;//定义myDragShadowBuilder的构造方法publicMyDragShadowBuilder(Viewv){//保存传给myDragShadowBuilder的View参数super(v);//创建一个可拖动的图像,用于填满系统给出的Canvasshadow=newColorDrawable(Color.LTGRAY);}//定义一个回调方法,用于把拖动阴影的大小和触摸点位置返回给系统@OverridepublicvoidonProvideShadowMetrics(Pointsize,Pointtouch)//定义本地变量privateintwidth,height;//把阴影的宽度设为原始View的一半width=getView().getWidth()/2;//把阴影的高度设为原始View的一半height=getView().getHeight()/2;//拖动阴影是一个ColorDrawable对象。//下面把它设为与系统给出的Canvas一样大小。这样,拖动阴影将会填满整个Canvas。shadow.setBounds(0,0,width,height);//设置长宽值,通过size参数返回给系统。size.set(width,height);//把触摸点的位置设为拖动阴影的中心touch.set(width/2,height/2);}//定义回调方法,用于在Canvas上绘制拖动阴影,Canvas由系统根据onProvideShadowMetrics()传入的尺寸参数创建。@OverridepublicvoidonDrawShadow(Canvascanvas){//在系统传入的Canvas上绘制ColorDrawableshadow.draw(canvas);}}

private static class MyDragShadowBuilder extends View.DragShadowBuilder {// 拖动阴影图像,定义为一个drawableprivate static Drawable shadow;// 定义myDragShadowBuilder的构造方法public MyDragShadowBuilder(View v) {// 保存传给myDragShadowBuilder的View参数super(v);// 创建一个可拖动的图像,用于填满系统给出的Canvasshadow = new ColorDrawable(Color.LTGRAY);}// 定义一个回调方法,用于把拖动阴影的大小和触摸点位置返回给系统@Overridepublic void onProvideShadowMetrics (Point size, Point touch)// 定义本地变量private int width, height;// 把阴影的宽度设为原始View的一半width = getView().getWidth() / 2;// 把阴影的高度设为原始View的一半height = getView().getHeight() / 2;// 拖动阴影是一个ColorDrawable对象。// 下面把它设为与系统给出的Canvas一样大小。这样,拖动阴影将会填满整个Canvas。shadow.setBounds(0, 0, width, height);// 设置长宽值,通过size参数返回给系统。size.set(width, height);// 把触摸点的位置设为拖动阴影的中心touch.set(width / 2, height / 2);}// 定义回调方法,用于在Canvas上绘制拖动阴影,Canvas由系统根据onProvideShadowMetrics()传入的尺寸参数创建。@Overridepublic void onDrawShadow(Canvas canvas) {// 在系统传入的Canvas上绘制ColorDrawableshadow.draw(canvas);}}

注意:请记住你不必扩展View.DragShadowBuilder。构造器View.DragShadowBuilder(View)创建一个默认与传入的参数View大小相同的拖动阴影,其中触摸点位于拖动阴影的中心。

响应拖动开始事件

在拖动过程中,系统会向当前layout中View对象的拖动事件侦听器发送拖动事件。侦听器应该调用getAction()来获取action类型。在开始拖动时,该方法返回ACTION_DRAG_STARTED。

为了响应带action类型ACTION_DRAG_STARTED的事件,侦听器应该完成以下工作:

调用getClipDescription()来获取ClipDescription。使用ClipDescription的方法来获取MIME类型,以确定侦听器是否接受拖动的数据。

如果拖放操作不是用于转移数据的,这步可能就不需要了。

如果侦听器可以接受拖动,则应该返回true。这将告诉系统以后还要向该侦听器发送拖动事件。 如果不能接受拖动,则它应该返回false,系统将会在发出ACTION_DRAG_ENDED之前停止向它发送拖动事件。

请注意,对于ACTION_DRAG_STARTED事件而言,DragEvent的以下方法是不可用的:getClipData()、getX()、getY()、getResult()。

拖动过程中的事件处理

在拖动过程中,响应ACTION_DRAG_STARTED拖动事件并返回true的侦听器将会持续接受拖动事件。 在拖动过程中,侦听器收到的拖动事件类型取决于拖动阴影的位置和侦听器所属View的可见性。

在拖动过程中,侦听器主要依据拖动事件来确定是否要修改View的外观。

在拖动过程中,getAction()返回以下三种类型之一:

ACTION_DRAG_ENTERED: 当触摸点(用户手指所触摸的屏幕点位)进入侦听器所属View的屏幕边界内。侦听器将收到此值。ACTION_DRAG_LOCATION: 一旦侦听器收到一个ACTION_DRAG_ENTERED事件,且之前已收到过一个ACTION_DRAG_EXITED事件,则每次触摸点移动时它会收到一个新的ACTION_DRAG_LOCATION事件。getX()和getY()方法返回触摸点的X和Y坐标。ACTION_DRAG_EXITED: 当拖动阴影移出侦听器所在View的边界内后,本事件将发送给之前已收到过ACTION_DRAG_ENTERED的侦听器。

侦听器不需要对这些action类型返回值。如果侦听器向系统返回一个值,将会被忽略。下面列出了一些响应这些action类型需要遵守的规则:

在对ACTION_DRAG_ENTERED或ACTION_DRAG_LOCATION的响应过程中,侦听器可以修改View的外观,以便显示出将要接受放下操作。带有action类型ACTION_DRAG_LOCATION的事件包含了getX()和getY()所需的数据,表示触摸点的坐标位置。侦听器可能要用这个信息来改变View上触摸点附近的外观。 侦听器还可以用此信息来确定用户将要放下拖动阴影的确切位置。在对ACTION_DRAG_EXITED响应过程中,侦听器应该把响应ACTION_DRAG_ENTERED或ACTION_DRAG_LOCATION时对外观的改动恢复原状。这向用户表明此View不再是作为放下操作的目的地了。

响应放下事件

当用户在应用程序的某个View上释放了拖动阴影,并且这个View之前已声明它可以接受被拖动的内容,系统就会向此View发送一个带有View类型ACTION_DROP的拖动事件。侦听器应该完成以下工作:

调用getClipData()来获取先前提交给startDrag()的ClipData对象,并保存下来。如果拖放操作不是用于数据转移,则此步不是必须的。返回布尔值true,表明放下操作处理完成,或返回false表示不成功。 这个返回值会成为ACTION_DRAG_ENDED事件中getResult()的返回值,

请注意,如果系统没有发出ACTION_DROP事件,ACTION_DRAG_ENDED中getResult()的返回值将会是false。

针对ACTION_DROP事件,getX()和getY()将返回放下时拖动点的X和Y坐标,采用收到放下操作的View的坐标系。

系统允许用户在侦听器不接收拖动事件的View上释放拖动阴影,也允许用户在应用程序界面的空白区域上释放拖动阴影,甚至在应用程序之外的区域也可以。 在这些情况下,系统都不会发送带有action类型ACTION_DROP的事件,不过会发出一个ACTION_DRAG_ENDED事件。

响应拖动结束事件

一旦用户释放了拖动阴影,系统会立即向应用程序内所有的拖动事件侦听器发送一个拖动事件,其中附带action类型ACTION_DRAG_ENDED。这表明拖动操作已经结束。

所有侦听器都应完成以下工作:

如果侦听器在运行过程中修改了View对象的外观,它应该将View恢复为默认画面。这向用户显示出拖放操作已完成。侦听器可选择调用getResult()来获取更多关于拖放操作的信息。如果侦听器在响应action类型为ACTION_DROP的事件时返回true,则getResult()将返回布尔值true。 除此之外,包括系统未发出ACTION_DROP事件时,getResult()都会返回布尔值false。侦听器应该向系统返回true。

响应拖动事件的示例

所有的拖动事件首先都是由你的拖动事件方法或侦听器接收的。以下代码片段简单演示了一个在侦听器中响应拖动事件的例子:

[java]view plaincopyprint? //新建一个拖动事件侦听器mDragListen=newmyDragEventListener();ViewimageView=newImageView(this);//为View设置拖动事件侦听器imageView.setOnDragListener(mDragListen);...protectedclassmyDragEventListenerimplementsView.OnDragEventListener{//这是系统向侦听器发送拖动事件时将会调用的方法publicbooleanonDrag(Viewv,DragEventevent){//定义一个变量,用于保存收到事件的action类型finalintaction=event.getAction();//处理所有需要的事件switch(action){caseDragEvent.ACTION_DRAG_STARTED://确定本View是否接受拖动数据if(event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)){//作为例子,把View的色彩滤镜设置蓝色,表示它可以接受数据。v.setColorFilter(Color.BLUE);//标明View强制用新的颜色重绘v.invalidate();//返回true表示View可以接受拖动数据return(true);}else{//返回false。在本次拖放操作中,本View不再会收到拖放事件,除非发出了ACTION_DRAG_ENDED。return(false);}break;caseDragEvent.ACTION_DRAG_ENTERED:{//把View的色彩滤镜设置为绿色。返回true,但返回值将被忽略。v.setColorFilter(Color.GREEN);//表明本View强制用新的颜色重绘v.invalidate();return(true);break;caseDragEvent.ACTION_DRAG_LOCATION://忽略事件return(true);break;caseDragEvent.ACTION_DRAG_EXITED://重新设置为蓝色。返回true,但返回值将被忽略。v.setColorFilter(Color.BLUE);//让view失效,以便强制用新的颜色重绘。v.invalidate();return(true);break;caseDragEvent.ACTION_DROP://获取包含拖动数据的itemClipData.Itemitem=event.getClipData().getItemAt(0);//从数据项中获取文本数据dragData=item.getText();//显示一个包含拖动数据的信息Toast.makeText(this,"Draggeddatais"+dragData,Toast.LENGTH_LONG);//去除所有色彩滤镜v.clearColorFilter();//让view失效,以便强制用新的颜色重绘。v.invalidate();//返回true。DragEvent.getResult()也将返回true.return(true);break;caseDragEvent.ACTION_DRAG_ENDED://去除所有色彩滤镜v.clearColorFilter();//让view失效,以便强制用新的颜色重绘。v.invalidate();//执行getResult(),显示操作的结果。if(event.getResult()){Toast.makeText(this,"Thedropwashandled.",Toast.LENGTH_LONG);}else{Toast.makeText(this,"Thedropdidn'twork.",Toast.LENGTH_LONG);};//返回true;返回值将被忽略return(true);break;//收到一个未知的actiontypedefault:Log.e("DragDropExample","UnknownactiontypereceivedbyOnDragListener.");break;};};};

// 新建一个拖动事件侦听器mDragListen = new myDragEventListener();View imageView = new ImageView(this);// 为View设置拖动事件侦听器imageView.setOnDragListener(mDragListen);...protected class myDragEventListener implements View.OnDragEventListener {// 这是系统向侦听器发送拖动事件时将会调用的方法public boolean onDrag(View v, DragEvent event) {// 定义一个变量,用于保存收到事件的action类型final int action = event.getAction();// 处理所有需要的事件switch(action) {case DragEvent.ACTION_DRAG_STARTED:// 确定本View是否接受拖动数据if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {// 作为例子,把View的色彩滤镜设置蓝色,表示它可以接受数据。v.setColorFilter(Color.BLUE);// 标明View强制用新的颜色重绘v.invalidate();// 返回true表示View可以接受拖动数据return(true);} else {// 返回false。在本次拖放操作中,本View不再会收到拖放事件,除非发出了ACTION_DRAG_ENDED。return(false);}break;case DragEvent.ACTION_DRAG_ENTERED: {// 把View的色彩滤镜设置为绿色。返回true,但返回值将被忽略。v.setColorFilter(Color.GREEN);// 表明本View强制用新的颜色重绘v.invalidate();return(true);break;case DragEvent.ACTION_DRAG_LOCATION:// 忽略事件return(true);break;case DragEvent.ACTION_DRAG_EXITED:// 重新设置为蓝色。返回true,但返回值将被忽略。v.setColorFilter(Color.BLUE);// 让view失效,以便强制用新的颜色重绘。v.invalidate();return(true);break;case DragEvent.ACTION_DROP:// 获取包含拖动数据的itemClipData.Item item = event.getClipData().getItemAt(0);// 从数据项中获取文本数据dragData = item.getText();// 显示一个包含拖动数据的信息Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);// 去除所有色彩滤镜v.clearColorFilter();// 让view失效,以便强制用新的颜色重绘。v.invalidate();// 返回true。 DragEvent.getResult()也将返回true.return(true);break;case DragEvent.ACTION_DRAG_ENDED:// 去除所有色彩滤镜v.clearColorFilter();// 让view失效,以便强制用新的颜色重绘。v.invalidate();// 执行getResult(),显示操作的结果。if (event.getResult()) {Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);} else {Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);};// 返回true; 返回值将被忽略return(true);break;// 收到一个未知的action typedefault:Log.e("DragDrop Example","Unknown action type received by OnDragListener.");break;};};};

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。