概述
Drag and Drop
使用Android拖拽框架,可以使你把数据从一个View移动到其他View中,这个框架包含一个Drop事件类,drop监听者和一个帮助方法。
虽然这个框架设计用来移动数据,但是你也可以用它做一些动作。例如你可以更改应用颜色,通过把一个颜色的图标拖拽到另一个图标上时。这个章节介绍,拖拽操作在移动数据方面的作用。
Overview
一个拖拽操作开始于用户开始拖拽数据的表象。在交互中,应用告诉系统拖拽开始。系统再回调数据移动开始。用户手指触摸这个数据的表象,系统发送一个Drop事件给App的Drap事件监听者,并且他调用相关View对象的Drap回调事件。用户释放了拖拽的阴影,这个Drap事件结束。
你要创建一个drap事件监听对象可以实现View.OnDrapListener接口。并用View.setDrapListener把监听者对象加入。每一个View对象都有一个onDrapEvent回调函数。
当你开始一个拖拽操作时,一个数据和描绘这个数据的元数据将作为事件的一部分发送给系统。在拖拽期间,系统把这两个数据发送给事件监听器和回调函数。当拖拽结束时,那个监听器或者回调函数可以用元数据决定这个view是否接受那个数据。
你的应用告诉系统开始拖拽使用StartDrap()方法。他告诉系统可以发送Drap事件了。这个事件也发送数据。你可以在一个View对象上调用startDrap方法。系统仅使用在View对象上全局设置。当你的应用调用startdrap方法时,你的程序的剩余部分用来发送到View对象中。
The drag/drop process
有四个基本步骤:
Start
当你开始拖拽时,你的应用用startDrap方法告诉系统拖拽开始了。这个方法用参数传入数据、元数据、和一个要绘制的拖拽阴影。
系统第一响应拖拽操作,这个时候他先获得拖拽的阴影,并把它显示在设备上。
下一步系统发送ACTION_DRAP_STARTED类型的拖拽事件,给所有在当前布局下的所有View对象。继续接收拖拽事件,并包含一个可能的丢弃事件,一个Drap监听者必须返回为真。这个监听者注册到系统的。仅仅注册的监听者接收Drap事件。这个时候,监听器可以改变View的外貌说明它可以接受丢弃事件。
如果监听器返回false,说明这个监听器不能接收Drap事件直到系统放送一个类型为ACTION_DRAP_ENDED的事件。当发送false时,监听器告诉系统他对Drap事件不感兴趣并且不想接收Drap事件。
Continuing
用户继续拖拽,当拖拽阴影和View对象的边框相交时,系统发送更多Drap事件给View的拖拽监听器。监听器可以决定改变View的外貌去接收这个drap事件。例如:当拖拽的阴影到达某个View的边际时系统发送一个(ACTION_DRAG_ENTERED类型的事件),监听器可以使这个View高亮显示。
Dropped
当用户在View对象的边框里放开拖拽阴影时,View对象接受了数据。系统发送给View对象一个类型为ACTION_DROP的事件。包含了数据的Drap事件被发送到系统中的startDrap()方法。监听器返回一个true告诉系统他成功接受了数据。
注意这个事件只发生在拖拽阴影被放开在接受这个Drap事件数据的View对象中时,才发送。
Ended
当View接收了数据,并且系统发送了ACTION_DROP的Drap事件后,系统发送一个ACTION_DRAP_ENDED类型的drap事件表明拖拽结束。当拖拽阴影被释放时这个事件都会被发送。所有注册过监听器的View都会接收到这个事件,甚至包括已经接收了ACTION_DROP事件的View对象。
这是Drap和Drop的详细过程描述。
The drag event listener and callback method
一个View对象要接收Drap事件就是要实现一个监听器对象(OnDrapListener)或者一个回调函数onDrapEvent(DrapEvent),并且传入一个DrapEvent对象。
在大多数任务中使用监听器,在自定义对象中使用回调函数。你可以实现一个监听器使用它注册给不同的View对象你也可以在一行中,实现一个匿名的监听器对象。使用setDrapListener方法注册监听器。
你可以两者都实现,但是系统只会调用监听器,直到监听器对象返回false值。
Drag events
系统通过DrapEvent对象发送Drap事件。它包含一个事件类型用来表明事件的状态。并且还包含一个数据。
可以通过getAction方法来取得类型。他们有六种类型在表格1中。
DrapEvent对象还包含数据,提供给应用调用startDrap()给系统。一些数据仅在某个类型的DrapEvent对象中有效。他们被总结道表格2中。
Table 1. DragEvent action
types
getAction() value
Meaning
A View object's drag event listener receives this event action type
just after the application calls and
gets a drag shadow.
A View object's drag event listener receives this event action type
when the drag shadow has just entered the bounding box of the View.
This is the first event action type the listener receives when the
drag shadow enters the bounding box. If the listener wants to
continue receiving drag events for this operation, it must return
boolean trueto the
system.
A View object's drag event listener receives this event action type
after it receives aevent
while the drag shadow is still within the bounding box of the
View.
A View object's drag event listener receives this event action type
after it receives aand
at least one event,
and after the user has moved the drag shadow outside the bounding
box of the View.
A View object's drag event listener receives this event action type
when the user releases the drag shadow over the View object. This
action type is only sent to a View object's listener if the
listener returned boolean true in
response to thedrag
event. This action type is not sent if the user releases the drag
shadow on a View whose listener is not registered, or if the user
releases the drag shadow on anything that is not part of the
current layout.
The listener is expected to return
boolean true if
it successfully processes the drop. Otherwise, it should
return false.
A View object's drag event listener receives this event action type
when the system is ending the drag operation. This action type is
not necessarily preceded by anevent.
If the system sent a to
get the value that was returned in response
to event
was not sent, then returns false.
Table 2. Valid DragEvent data by
action type
getAction、describeContents、writeToParcel和toString总能够调用。
如果一个方法不能返回有效数据他返回0或者null值。
The drag shadow
在拖拽期间,系统显示一个拖拽的图形。它代表数据被移动了。为了其他操作这个图片代表了一些Drag操作。
这个图片叫做拖拽阴影。你要创建他使用View.DragShadowBuilder对象。当系统调用startDrag方法时,系统调用定义在View.DragShadowBuilder的回调方法中的拖拽阴影。
这个对象有两个构造函数。
View.DragShadowBuilder(View)
这个构造函数接收一个View对象作为拖拽阴影。他和用户拖拽的View对象并不相关。你使用这个构造函数,你就不能继承View.DragShadowBuilder或者覆写他的方法。默认情况下,拖拽阴影在拖拽过程中都一样,并且被绑定在触摸的中央。
View.DragShadowBuilder()
如果你使用这个构造函数,系统将使用一个隐形的拖拽阴影。
这个对象有两个方法。
onProvideShadowMetrics()
这个方法在系统调用startDrag方法时马上调用。他用来告诉系统拖拽阴影是多大,怎样定位。他有两个参数:
尺寸:
一个Point对象,宽度为X,高度为Y
touch_point
一个Point对象,他定义在拖拽阴影内,用户手指下。X定位为X,Y定位为Y。
onDrawShadow()
在调用完上面的方法后调用这个方法。这个方法提供拖拽阴影的描绘。这个方法只有一个单一的对象,一个Canvas对象他的尺寸和位置由上面的方法提供。
为了性能方面的考虑,拖拽阴影最好尽量小。对单一选项,提供单一图标。当多选时,使用图标栈,而不是许多图标。
Designing a Drag and Drop Operation
这节中一步一步地介绍怎样设计一个拖拽过程。
Starting a drag
通常用户开始一个拖拽过程,都是通过长点击。这时你要做到下列步骤。
1、必须的,你要创建一个ClipData和ClipData.Item对象用来放置要移动的数据。在ClipData对象中放置ClipDescription对象代表元数据。如果一个拖拽操作,并不代表数据的移动,就用Null来替代。
例如:下面的片段显示怎样响应在一个图片组件上长按,并创建一个ClipData过程,之后的片段显示了如何覆写View.DragShadowBuilder中的方法。
1、//
Create a string for the ImageView label
privatestaticfinalStringIMAGEVIEW_TAG="icon bitmap"// Creates a new ImageViewImageViewimageView=newImageView(this);// Sets the bitmap for the ImageView from an icon bit map (defined elsewhere)imageView.setImageBitmap(mIconBitmap);// Sets the tagimageView.setTag(IMAGEVIEW_TAG);...// Sets a long click listener for the ImageView using an anonymous listener object that// implements the OnLongClickListener interfaceimageView.setOnLongClickListener(newView.OnLongClickListener(){// Defines the one method for the interface, which is called when the View is long-clickedpublicbooleanonLongClick(Viewv){// Create a new ClipData.// This is done in two steps to provide clarity. The convenience method// ClipData.newPlainText() can create a plain text ClipData in one step.// Create a new ClipData.Item from the ImageView object's tagClipData.Itemitem=newClipData.Item(v.getTag());// Create a new ClipData using the tag as a label, the plain text MIME type, and// the already-created item. This will create a new ClipDescription object within the// ClipData, and set its MIME type entry to "text/plain"ClipDatadragData=newClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);// Instantiates the drag shadow builder.View.DrawShadowBuildermyShadow=newMyDragShadowBuilder(imageView);// Starts the dragv.startDrag(dragData,// the data to be draggedmyShadow,// the drag shadow buildernull,// no need to use local data0// flags (not currently used, set to 0));}}
2、下列代码显示如何覆写View.DragShadowBuilder中的方法。他定义了一个拖拽文本框像一个灰色的矩形。
privatestaticclassMyDragShadowBuilderextendsView.DragShadowBuilder{// The drag shadow image, defined as a drawable thingprivatestaticDrawableshadow;// Defines the constructor for myDragShadowBuilderpublicMyDragShadowBuilder(Viewv){// Stores the View parameter passed to myDragShadowBuilder.super(v);// Creates a draggable image that will fill the Canvas provided by the system.shadow=newColorDrawable(Color.LTGRAY);}// Defines a callback that sends the drag shadow dimensions and touch point back to the// system.@OverridepublicvoidonProvideShadowMetrics(Pointsize,Pointtouch)// Defines local variablesprivateintwidth,height;// Sets the width of the shadow to half the width of the original Viewwidth=getView().getWidth()/2;// Sets the height of the shadow to half the height of the original Viewheight=getView().getHeight()/2;// The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the// Canvas that the system will provide. As a result, the drag shadow will fill the// Canvas.shadow.setBounds(0,0,width,height);// Sets the size parameter's width and height values. These get back to the system// through the size parameter.size.set(width,height);// Sets the touch point's position to be in the middle of the drag shadowtouch.set(width/2,height/2);}// Defines a callback that draws the drag shadow in a Canvas that the system constructs// from the dimensions passed in onProvideShadowMetrics().@OverridepublicvoidonDrawShadow(Canvascanvas){// Draws the ColorDrawable in the Canvas passed in from the system.shadow.draw(canvas);}}
注意你不能扩展View.DragShadowBuilder,它的构造函数创建一个默认的拖拽阴影。
Responding to a drag start
在拖拽期间,系统发送拖拽事件到每个注册的监听器。在监听器重调用getAction获得类型,如果是ACTION_DRAG_STARTED,监听器可以做一些操作:
1、通过getClipDescription方法,获得ClipDescription对象。使用MIME类型方法看看ClipDescription信息是否可以被接受。
2、如果数据能被接收就返回true,这就告诉系统,对象可以被Drop。如果返回false,告诉系统不要发送Drag事件,直到发送ACTION_DRAG_ENDED事件。
Handling events during the drag
在拖拽期间,监听器返回真去响应ACTION_DRAG_STARTED类型事件,说明可以继续接收拖拽事件。这个时候的监听器接收事件就依赖于拖拽阴影的位置和View对象的能力。
在拖拽期间,监听器使用拖拽事件来决定View对象的外观。
如果返回这三个值的一个
event,
and before it receives an Aevent,
it receives a new event
every time the touch point moves. Theand methods
return the the X and Y coordinates of the touch point.
监听器并不需要响应这些类型的Drag事件,可以使用一个值来忽略这些值。
这里有一些原则供你参考:
在响应ACTION_DRAG_ENTERED和ACTION_DRAG_LOCATION,监听器可以改变View的外观,
在响应ACTION_DRAG_LOCATION时,可以通过getX和getY方法获得拖拽阴影的位置,用来改变外观,或者定位Drop事件发生时,阴影所在位置。
在响应ACTION_DRAG_EXITED时,可以还原View的外观,这表明用户把阴影拖到不接受Drop事件View上。
Responding to a drop
当用户释放拖拽阴影时,View预先报告能够接受的数据,系统发送一个ACTION_DROP事件。监听器可以做下列操作:
1、通过getClipData方法获得ClipData对象。如果不是移动对象这个操作不需要。
2、返回真说明Drop操作成功了,或者返回假说不能接收。这个返回值将变成ACTION_DRAG_END中的返回值。
对于ACTION_DROP,getX和getY说明了drop事件发生时,拖拽阴影在View中的位置。
当系统接收Drop事件时而监听器不接收这个事件时,系统也会允许释放拖拽阴影在一个空白区域或者屏幕之外。这时系统不会发送ACTION_DROP事件,但是会发送ACTION_DRAG_END事件。
Responding to a drag end
在用户释放拖拽阴影时,系统发送一个ACTION_DRAG_ENDED事件。
监听器做以下操作:
1、如果在拖拽期间改变了View的外观,这个时候要还原回去,这个表示拖拽结束了。
2、监听器可以调用getResult方法获得关于这个拖拽操作的信息。如果返回true,说明接收了数据,ACTION_DROP类型事件被发送。如果返回false说明数据没有被接收,ACTION_DROP事件没有被接受。
3、这个监听器返回true给系统。
Responding to drag events: an example
所有事件响应都写在监听器或者回调函数中。
// Creates a new drag event listenermDragListen=newmyDragEventListener();ViewimageView=newImageView(this);// Sets the drag event listener for the ViewimageView.setOnDragListener(mDragListen);...protectedclassmyDragEventListenerimplementsView.OnDragEventListener{// This is the method that the system calls when it dispatches a drag event to the// listener.publicbooleanonDrag(Viewv,DragEventevent){// Defines a variable to store the action type for the incoming eventfinalintaction=event.getAction();// Handles each of the expected eventsswitch(action){caseDragEvent.ACTION_DRAG_STARTED:// Determines if this View can accept the dragged dataif(event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)){// As an example of what your application might do,// applies a blue color tint to the View to indicate that it can accept// data.v.setColorFilter(Color.BLUE);// Invalidate the view to force a redraw in the new tintv.invalidate();// returns true to indicate that the View can accept the dragged data.return(true);}else{// Returns false. During the current drag and drop operation, this View will// not receive events again until ACTION_DRAG_ENDED is sent.return(false);}break;caseDragEvent.ACTION_DRAG_ENTERED:{// Applies a green tint to the View. Return true; the return value is ignored.v.setColorFilter(Color.GREEN);// Invalidate the view to force a redraw in the new tintv.invalidate();return(true);break;caseDragEvent.ACTION_DRAG_LOCATION:// Ignore the eventreturn(true);break;caseDragEvent.ACTION_DRAG_EXITED:// Re-sets the color tint to blue. Returns true; the return value is ignored.v.setColorFilter(Color.BLUE);// Invalidate the view to force a redraw in the new tintv.invalidate();return(true);break;caseDragEvent.ACTION_DROP:// Gets the item containing the dragged dataClipData.Itemitem=event.getClipData().getItemAt(0);// Gets the text data from the item.dragData=item.getText();// Displays a message containing the dragged data.Toast.makeText(this,"Dragged data is "+dragData,Toast.LENGTH_LONG);// Turns off any color tintsv.clearColorFilter();// Invalidates the view to force a redrawv.invalidate();// Returns true. DragEvent.getResult() will return true.return(true);break;caseDragEvent.ACTION_DRAG_ENDED:// Turns off any color tintingv.clearColorFilter();// Invalidates the view to force a redrawv.invalidate();// Does a getResult(), and displays what happened.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);};// returns true; the value is ignored.return(true);break;// An unknown action type was received.default:Log.e("DragDrop Example","Unknown action type received by OnDragListener.");break;};};};
最后
以上就是落寞啤酒为你收集整理的android实训报告日记,Android学习日记(10)的全部内容,希望文章能够帮你解决android实训报告日记,Android学习日记(10)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复