Android Drag And Drop Example

Android support drag and drop action since SDK version 11. You can drag any view component from the source container and drop it to another container ( view component ). This example will show you how to implement drag and drop action in android.

1. Android Drag And Drop Implementation Steps.

1.1 For Being Dragged View.

  1. Create a custom on-touch listener class that implements the android.view.View.OnTouchListener interface.
  2. Override it’s onTouch method, start drag and hide the dragged view object in this method.
  3. Invoke dragged view’s setOnTouchListener method to set an instance of custom on-touch listener object to it. Then when the user touches the source dragged view component, the listener’s onTouch method will be invoked.

1.2 For Dropped Target View.

  1. Create a custom on-drag listener class that implements the android.view.View.OnDragListener interface.
  2. Override the onDrag method in the custom class.
  3. Get drag action value from the drag event input parameter of the onDrag method.
  4. Implement code to related drag actions such as ( DragEvent.ACTION_DRAG_STARTED, DragEvent.ACTION_DROP etc).
  5. Call target view’s setOnDragListener method and add an instance of custom on-drag listener object to it.
  6. Then when the source view object is dragged enter, over, exit, or drop to the target view, the custom on-drag listener can execute the onDrag method to respond.

2. Android Drag And Drop Example.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/aKtl5BePAqQ

  1. There are two columns in this example. Each column is a LinearLayout object.
  2. There is a button and an image view in the left LinearLayout.
  3. When the button or the image view is dragged to right, the background color will change accordingly. And a Toast popup will be shown with related messages.
  4. The below shows the java files in this project. There are two listeners and one activity.
    C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\GESTUREEXAMPLE\APP\SRC\MAIN\JAVA\COM\DEV2QA\GESTUREEXAMPLE
    └───dragdrop
            DragDropActivity.java
            DragDropOnDragListener.java
            DragDropOnTouchListener.java
    

3. Main Activity Java File.

  1. DragDropActivity.java
    package com.dev2qa.gestureexample.dragdrop;
    
    import android.content.Context;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    
    import com.dev2qa.gestureexample.R;
    
    public class DragDropActivity extends AppCompatActivity {
    
        private Button button = null;
    
        private ImageView imageView = null;
    
        private LinearLayout linearLayoutLeft = null;
    
        private LinearLayout linearLayoutRight = null;
    
        private Context context = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_drag_drop);
    
            setTitle("dev2qa.com - Android Drag & Drop Example.");
    
            // Init all controls.
            initControls();
        }
    
        private void initControls()
        {
    
            if(context == null)
            {
                context = getApplicationContext();
            }
    
            if(button == null)
            {
                button = (Button)findViewById(R.id.drag_drop_button);
    
                // Set a tag.
                button.setTag("Button");
    
                // Set on touch listener to source dragged view.
                button.setOnTouchListener(new DragDropOnTouchListener());
            }
    
            if(imageView == null)
            {
                imageView = (ImageView) findViewById(R.id.drag_drop_image);
    
                imageView.setTag("ImageView");
    
                // Set on touch listener to source dragged view.
                imageView.setOnTouchListener(new DragDropOnTouchListener());
    
            }
    
            if(linearLayoutLeft == null)
            {
                linearLayoutLeft = (LinearLayout)findViewById(R.id.drag_drop_left_layout);
    
                // Set on drag listener to target dropped view.
                linearLayoutLeft.setOnDragListener(new DragDropOnDragListener(context));
            }
    
            if(linearLayoutRight == null)
            {
                linearLayoutRight = (LinearLayout)findViewById(R.id.drag_drop_right_layout);
    
                // Set on drag listener to target dropped view.
                linearLayoutRight.setOnDragListener(new DragDropOnDragListener(context));
            }
        }
    }

4. Custom On Touch Listener.

  1. DragDropOnTouchListener.java
    package com.dev2qa.gestureexample.dragdrop;
    
    import android.content.ClipData;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class DragDropOnTouchListener implements View.OnTouchListener {
    
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
    
            // Get view object tag value.
            String tag = (String)view.getTag();
    
            // Create clip data.
            ClipData clipData = ClipData.newPlainText("", tag);
    
            // Create drag shadow builder object.
            View.DragShadowBuilder dragShadowBuilder = new View.DragShadowBuilder(view);
    
    
            /* Invoke view object's startDrag method to start the drag action.
               clipData : to be dragged data.
               dragShadowBuilder : the shadow of the dragged view.
            */
            view.startDrag(clipData, dragShadowBuilder, view, 0);
    
    
            // Hide the view object because we are dragging it.
            view.setVisibility(View.INVISIBLE);
    
            return true;
        }
    }

5. Custom On Drag Listener.

  1. DragDropOnDragListener.java
    package com.dev2qa.gestureexample.dragdrop;
    
    import android.content.ClipData;
    import android.content.ClipDescription;
    import android.content.Context;
    import android.graphics.Color;
    import android.graphics.PorterDuff;
    import android.view.DragEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    import android.widget.Toast;
    
    
    public class DragDropOnDragListener implements View.OnDragListener {
    
        private Context context = null;
    
        public DragDropOnDragListener(Context context) {
            this.context = context;
        }
    
        @Override
        public boolean onDrag(View view, DragEvent dragEvent) {
    
            // Get the drag drop action.
            int dragAction = dragEvent.getAction();
    
            if(dragAction == dragEvent.ACTION_DRAG_STARTED)
            {
                // Check whether the dragged view can be placed in this target view or not.
    
                ClipDescription clipDescription = dragEvent.getClipDescription();
    
                if (clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
    
                    // Return true because the target view can accept the dragged object.
                    return true;
    
                }
            }else if(dragAction == dragEvent.ACTION_DRAG_ENTERED)
            {
                // When the being dragged view enter the target view, change the target view background color.
                changeTargetViewBackground(view, Color.GREEN);
    
                return true;
            }else if(dragAction == dragEvent.ACTION_DRAG_EXITED)
            {
                // When the being dragged view exit target view area, clear the background color.
                resetTargetViewBackground(view);
    
                return true;
            }else if(dragAction == dragEvent.ACTION_DRAG_ENDED)
            {
    
                // When the drop ended reset target view background color.
                resetTargetViewBackground(view);
    
                // Get drag and drop action result.
                boolean result = dragEvent.getResult();
    
                // result is true means drag and drop action success.
                if(result)
                {
                    Toast.makeText(context, "Drag and drop action complete successfully.", Toast.LENGTH_LONG).show();
                }else
                {
                    Toast.makeText(context, "Drag and drop action failed.", Toast.LENGTH_LONG).show();
                }
    
                return true;
    
            }else if(dragAction == dragEvent.ACTION_DROP)
            {
                // When drop action happened.
    
                // Get clip data in the drag event first.
                ClipData clipData = dragEvent.getClipData();
    
                // Get drag and drop item count.
                int itemCount = clipData.getItemCount();
    
                // If item count bigger than 0.
                if(itemCount > 0) {
                    // Get clipdata item.
                    ClipData.Item item = clipData.getItemAt(0);
    
                    // Get item text.
                    String dragDropString = item.getText().toString();
    
                    // Show a toast popup.
                    Toast.makeText(context, "Dragged object is a " + dragDropString, Toast.LENGTH_LONG).show();
    
                    // Reset target view background color.
                    resetTargetViewBackground(view);
    
                    // Get dragged view object from drag event object.
                    View srcView = (View)dragEvent.getLocalState();
                    // Get dragged view's parent view group.
                    ViewGroup owner = (ViewGroup) srcView.getParent();
                    // Remove source view from original parent view group.
                    owner.removeView(srcView);
    
                    // The drop target view is a LinearLayout object so cast the view object to it's type.
                    LinearLayout newContainer = (LinearLayout) view;
                    // Add the dragged view in the new container.
                    newContainer.addView(srcView);
                    // Make the dragged view object visible.
                    srcView.setVisibility(View.VISIBLE);
    
                    // Returns true to make DragEvent.getResult() value to true.
                    return true;
                }
    
            }else if(dragAction == dragEvent.ACTION_DRAG_LOCATION)
            {
               return true;
            }else
            {
                Toast.makeText(context, "Drag and drop unknow action type.", Toast.LENGTH_LONG).show();
            }
    
            return false;
        }
    
    
        /* Reset drag and drop target view's background color. */
        private void resetTargetViewBackground(View view)
        {
            // Clear color filter.
            view.getBackground().clearColorFilter();
    
            // Redraw the target view use original color.
            view.invalidate();
        }
    
    
        /* Change drag and drop target view's background color. */
        private void changeTargetViewBackground(View view, int color)
        {
            /* When the being dragged view enter the target view, change the target view background color.
            *
            *  color : The changed to color value.
            *
            *  mode : When to change the color, SRC_IN means source view ( dragged view ) enter target view.
            * */
            view.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    
            // Redraw the target view use new color.
            view.invalidate();
        }
    }

6. Main Layout Xml File.

  1. activity_drag_drop.xml
  2. This file is saved in the app/res/layout folder.
    <GridLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnCount="2"
        android:orientation="horizontal">
    
        <LinearLayout
            android:id="@+id/drag_drop_left_layout"
            android:orientation="vertical"
            android:background="@drawable/drag_drop_background"
            android:layout_width="215dp"
            android:layout_height="match_parent"
            android:gravity="center">
    
            <Button
                android:id="@+id/drag_drop_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Drag and drop me to right"
                android:textAllCaps="false"
                android:textSize="10dp"/>
    
            <ImageView
                android:id="@+id/drag_drop_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/ic_launcher"
                android:layout_marginTop="20dp"/>
    
        </LinearLayout>
    
    
        <LinearLayout
            android:id="@+id/drag_drop_right_layout"
            android:layout_width="215dp"
            android:layout_height="match_parent"
            android:background="@color/colorPrimaryDark"
            android:orientation="vertical">
    
    
        </LinearLayout>
    
    </GridLayout>

7. Left Column Background Drawable Shape Xml File.

  1. drag_drop_background.xml
  2. This file is saved in the app/res/drawable folder.
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    
        <gradient
            android:angle="0"
            android:startColor="@color/colorAccent"
            android:endColor="@color/colorPrimary" />
    
        <stroke
            android:width="1dp"
            android:color="#DDDDDDDD" />
    
        <corners
            android:topLeftRadius="5dp"
            android:topRightRadius="5dp"
            android:bottomLeftRadius="5dp"
            android:bottomRightRadius="5dp" />
    
    </shape>

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.