android - Drag and Drop

来源:互联网 发布:手机截图软件 编辑:程序博客网 时间:2024/04/18 12:08

> With the Android drag/drop framework, you can allow your users to move data from one View to another View in the current layout using a graphical drag and drop gesture. The framework includes a drag event class, drag listeners, and helper methods and classes.

A View receives drag events with either a drag event listener that implements View.OnDragListener or with itsonDragEvent(DragEvent) callback method. When the system calls the method or listener, it passes to them aDragEvent object.

>To get the action type, a listener calls getAction(). There are six possible values, defined by constants in theDragEvent class. These are listed in table 1.

ACTION_DRAG_STARTED ACTION_DRAG_ENTERED ACTION_DRAG_LOCATION ACTION_DRAG_EXITED ACTION_DROP ACTION_DRAG_ENDED 

// Create a string for the ImageView labelprivate static final String IMAGEVIEW_TAG = "icon bitmap"// Creates a new ImageViewImageView imageView = new ImageView(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(new View.OnLongClickListener() {    // Defines the one method for the interface, which is called when the View is long-clicked    public boolean onLongClick(View v) {    // 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 tag    ClipData.Item item = new ClipData.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"    ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);    // Instantiates the drag shadow builder.    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView);    // Starts the drag            v.startDrag(dragData,  // the data to be dragged                        myShadow,  // the drag shadow builder                        null,      // no need to use local data                        0          // flags (not currently used, set to 0)            );    }}

> The following code snippet defines myDragShadowBuilder It creates a drag shadow for dragging a TextView as a small gray rectangle:

    private static class MyDragShadowBuilder extends View.DragShadowBuilder {    // The drag shadow image, defined as a drawable thing    private static Drawable shadow;        // Defines the constructor for myDragShadowBuilder        public MyDragShadowBuilder(View v) {            // Stores the View parameter passed to myDragShadowBuilder.            super(v);            // Creates a draggable image that will fill the Canvas provided by the system.            shadow = new ColorDrawable(Color.LTGRAY);        }        // Defines a callback that sends the drag shadow dimensions and touch point back to the        // system.        @Override        public void onProvideShadowMetrics (Point size, Point touch)            // Defines local variables            private int width, height;            // Sets the width of the shadow to half the width of the original View            width = getView().getWidth() / 2;            // Sets the height of the shadow to half the height of the original View            height = 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 shadow            touch.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().        @Override        public void onDrawShadow(Canvas canvas) {            // Draws the ColorDrawable in the Canvas passed in from the system.            shadow.draw(canvas);        }    }
During the drag, listeners primarily use drag events to decide if they should change the appearance of their View.During the drag, getAction() returns one of three values:
  • ACTION_DRAG_ENTERED: The listener receives this when the touch point (the point on the screen underneath the user's finger) has entered the bounding box of the listener's View.
  • ACTION_DRAG_LOCATION: Once the listener receives an ACTION_DRAG_ENTERED event, and before it receives an AACTION_DRAG_EXITED event, it receives a new ACTION_DRAG_LOCATION event every time the touch point moves. The getX() and getY() methods return the X and Y coordinates of the touch point.
  • ACTION_DRAG_EXITED: This event is sent to a listener that previously received ACTION_DRAG_ENTERED, after the drag shadow is no longer within the bounding box of the listener's View.
All drag events are initially received by your drag event method or listener. The following code snippet is a simple example of reacting to drag events in a listener:
// Creates a new drag event listenermDragListen = new myDragEventListener();View imageView = new ImageView(this);// Sets the drag event listener for the ViewimageView.setOnDragListener(mDragListen);...protected class myDragEventListener implements View.OnDragListener {    // This is the method that the system calls when it dispatches a drag event to the    // listener.    public boolean onDrag(View v, DragEvent event) {        // Defines a variable to store the action type for the incoming event        final int action = event.getAction();        // Handles each of the expected events        switch(action) {            case DragEvent.ACTION_DRAG_STARTED:                // Determines if this View can accept the dragged data                if (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 tint                    v.invalidate();                    // returns true to indicate that the View can accept the dragged data.                    return true;                }                // Returns false. During the current drag and drop operation, this View will                // not receive events again until ACTION_DRAG_ENDED is sent.                return false;            case DragEvent.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 tint                v.invalidate();                return true;            case DragEvent.ACTION_DRAG_LOCATION:                // Ignore the event                return true;            case DragEvent.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 tint                v.invalidate();                return true;            case DragEvent.ACTION_DROP:                // Gets the item containing the dragged data                ClipData.Item item = 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 tints                v.clearColorFilter();                // Invalidates the view to force a redraw                v.invalidate();                // Returns true. DragEvent.getResult() will return true.                return true;            case DragEvent.ACTION_DRAG_ENDED:                // Turns off any color tinting                v.clearColorFilter();                // Invalidates the view to force a redraw                v.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;            // An unknown action type was received.            default:                Log.e("DragDrop Example","Unknown action type received by OnDragListener.");                break;        }                return false;    }};

0 0