Back to top

vogella training Training Books

Android Drag and Drop Tutorial

Lars Vogel

Version 1.1

06.01.2013

Revision History
Revision 0.1 14.02.2012   Created
Revision History
Revision 1.1 24.02.2012 - 06.01.2013   Bugfixes and enhancements

Drag and Drop in Android

This tutorial describes how to use drag and drop in Android. It is based on Eclipse 4.2 (Indigo), Java 1.6 and Android 4.2.


Table of Contents

1. Android Drag and Drop
1.1. Overview
1.2. Implementation
2. Exercise: Drag and drop
2.1. Create project
2.2. Create XML drawables
2.3. Activity and Layout
3. Thank you
4. Questions and Discussion
5. Links and Literature
5.1. Source Code
5.2. Android Resources
5.3. vogella Resources

1. Android Drag and Drop

1.1. Overview

As of Android 4.0 Drag and Drop of Views is supported. You register a listener on the View and you define other Views as possible drop targets, e.g. drop zones.

1.2. Implementation

To use this you register a listener on the View, e.g. a OnTouchListener or a LongClickListener.

In this method you construct an object of type ClipData. This object can be used to contain data which can be passed to the Views which are defined as drop zones.

The DragShadowBuilder allow you specify the look of the dragging operation. Typically you pass in the View directly, which will be shown for the drag operation.

// Assign the touch listener to your view which you want to move
findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener());

// This defines your touch listener
private final class MyTouchListener implements OnTouchListener {
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
      ClipData data = ClipData.newPlainText("", "");
      DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
      view.startDrag(data, shadowBuilder, view, 0);
      view.setVisibility(View.INVISIBLE);
      return true;
    } else {
    return false;
    }
  }
} 

A View which are used as a drop zone, gets a OnDragListener assigned via the setOnDragListener() method. In this OnDragListener you can evaluate the events and react accordingly.

findViewById(R.id.bottomright).setOnDragListener(new MyDragListener());

class MyDragListener implements OnDragListener {
  Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget);
  Drawable normalShape = getResources().getDrawable(R.drawable.shape);
  
  @Override
  public boolean onDrag(View v, DragEvent event) {
    int action = event.getAction();
    switch (event.getAction()) {
    case DragEvent.ACTION_DRAG_STARTED:
    // Do nothing
      break;
    case DragEvent.ACTION_DRAG_ENTERED:
      v.setBackgroundDrawable(enterShape);
      break;
    case DragEvent.ACTION_DRAG_EXITED:        
      v.setBackgroundDrawable(normalShape);
      break;
    case DragEvent.ACTION_DROP:
      // Dropped, reassign View to ViewGroup
      View view = (View) event.getLocalState();
      ViewGroup owner = (ViewGroup) view.getParent();
      owner.removeView(view);
      LinearLayout container = (LinearLayout) v;
      container.addView(view);
      view.setVisibility(View.VISIBLE);
      break;
    case DragEvent.ACTION_DRAG_ENDED:
      v.setBackgroundDrawable(normalShape);
      default:
      break;
    }
    return true;
  }
} 

2. Exercise: Drag and drop

2.1. Create project

Create a new Android project called de.vogella.android.draganddrop with an activity called DragActivity.

2.2. Create XML drawables

We are going to use XML drawables in this example.

Create the drawable folder in your res directory. Create the following shape.xml file in this folder.

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <stroke
        android:width="2dp"
        android:color="#FFFFFFFF" />

    <gradient
        android:angle="225"
        android:endColor="#DD2ECCFA"
        android:startColor="#DD000000" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape> 

Create the shape_droptarget.xml file in the drawable folder.

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <stroke
        android:width="2dp"
        android:color="#FFFF0000" />

    <gradient
        android:angle="225"
        android:endColor="#DD2ECCFA"
        android:startColor="#DD000000" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape> 

2.3. Activity and Layout

Change the layout of your activity to the following code.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2"
    android:columnWidth="300dp"
    android:orientation="vertical"
    android:rowCount="2"
    android:stretchMode="columnWidth" >

    <LinearLayout
        android:id="@+id/topleft"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="0"
        android:layout_row="0"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/topright"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="1"
        android:layout_row="0"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomleft"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="0"
        android:layout_row="1"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomright"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="1"
        android:layout_row="1"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

</GridLayout> 

Change your activity class to the following code.

package de.vogella.android.draganddrop;

import android.app.Activity;
import android.content.ClipData;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class DragActivity extends Activity {
  
/** Called when the activity is first created. */
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage2).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage3).setOnTouchListener(new MyTouchListener()); findViewById(R.id.myimage4).setOnTouchListener(new MyTouchListener()); findViewById(R.id.topleft).setOnDragListener(new MyDragListener()); findViewById(R.id.topright).setOnDragListener(new MyDragListener()); findViewById(R.id.bottomleft).setOnDragListener(new MyDragListener()); findViewById(R.id.bottomright).setOnDragListener(new MyDragListener()); } private final class MyTouchListener implements OnTouchListener { public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { ClipData data = ClipData.newPlainText("", ""); DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); view.startDrag(data, shadowBuilder, view, 0); view.setVisibility(View.INVISIBLE); return true; } else { return false; } } } class MyDragListener implements OnDragListener { Drawable enterShape = getResources().getDrawable(R.drawable.shape_droptarget); Drawable normalShape = getResources().getDrawable(R.drawable.shape); @Override public boolean onDrag(View v, DragEvent event) { int action = event.getAction(); switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: // Do nothing break; case DragEvent.ACTION_DRAG_ENTERED: v.setBackgroundDrawable(enterShape); break; case DragEvent.ACTION_DRAG_EXITED: v.setBackgroundDrawable(normalShape); break; case DragEvent.ACTION_DROP: // Dropped, reassign View to ViewGroup View view = (View) event.getLocalState(); ViewGroup owner = (ViewGroup) view.getParent(); owner.removeView(view); LinearLayout container = (LinearLayout) v; container.addView(view); view.setVisibility(View.VISIBLE); break; case DragEvent.ACTION_DRAG_ENDED: v.setBackgroundDrawable(normalShape); default: break; } return true; } } }

If you start this activity you should be able to drag the ImageViews to another container.

Drag and Drop Screenshot of the Application

3. Thank you

Please help me to support this article:

Flattr this

4. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.

5. Links and Literature

5.1. Source Code

Source Code of Examples

5.3. vogella Resources

vogella Training Android and Eclipse Training from the vogella team

Android Tutorial Introduction to Android Programming

GWT Tutorial Program in Java and compile to JavaScript and HTML

Eclipse RCP Tutorial Create native applications in Java

JUnit Tutorial Test your application

Git Tutorial Put everything you have under distributed version control system