How to implement Drag and Drop in android 2.2?

Solution 1:

Hi after long time a get the success of do the drag and drop in android 2.2

here i give my code which give you the success.My Main Class is Here

 package info.tempDD;

    import android.app.Activity;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.ViewGroup;
    import android.view.ViewGroup.LayoutParams;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;

   public class TempDDActivity extends Activity implements OnTouchListener {
        /** Called when the activity is first created. */
        private View selected_item = null;
        private int offset_x = 0;
        private int offset_y = 0;
        Boolean touchFlag=false;
        boolean dropFlag=false;
        LayoutParams imageParams;
        ImageView imageDrop,image1,image2;
        int crashX,crashY;
        Drawable dropDrawable,selectDrawable;
        Rect dropRect,selectRect;
        int topy,leftX,rightX,bottomY;

        int dropArray[];    

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.main);
            ViewGroup container = (ViewGroup) findViewById(R.id.container);
            imageDrop=(ImageView) findViewById(R.id.ImgDrop);       
            image1=(ImageView) findViewById(R.id.img);      
            image2=(ImageView) findViewById(R.id.img2);
            container.setOnTouchListener(new View.OnTouchListener() 
            {
                public boolean onTouch(View v, MotionEvent event) 
                {
                    if(touchFlag==true)
                    {
                        System.err.println("Display If  Part ::->"+touchFlag);
                        switch (event.getActionMasked()) 
                        {
                        case MotionEvent.ACTION_DOWN :

                             topy=imageDrop.getTop();
                             leftX=imageDrop.getLeft();
                             rightX=imageDrop.getRight();   
                             bottomY=imageDrop.getBottom();
                            System.err.println("Display Top-->"+topy);      
                            System.err.println("Display Left-->"+leftX);
                            System.err.println("Display Right-->"+rightX);
                            System.err.println("Display Bottom-->"+bottomY);                


                            //opRect.
                            break;
                        case MotionEvent.ACTION_MOVE:
                            crashX=(int) event.getX();
                            crashY=(int) event.getY();
                            System.err.println("Display Here X Value-->"+crashX);
                            System.err.println("Display Here Y Value-->"+crashY);

                            int x = (int) event.getX() - offset_x;
                            int y = (int) event.getY() - offset_y;                                          
                            //int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
                            //int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
                            int w = getWindowManager().getDefaultDisplay().getWidth() - 50;
                            int h = getWindowManager().getDefaultDisplay().getHeight() - 10;
                            if (x > w)
                                x = w;
                            if (y > h)
                                y = h;                      
                            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams(  RelativeLayout.LayoutParams.WRAP_CONTENT,   RelativeLayout.LayoutParams.WRAP_CONTENT));
                            lp.setMargins(x, y, 0, 0);                  

                            //Drop Image Here                       
                            if(crashX > leftX && crashX < rightX && crashY > topy && crashY < bottomY )                     
                            {                           
                                Drawable temp=selected_item.getBackground();                            
                                imageDrop.setBackgroundDrawable(temp);
                                imageDrop.bringToFront();                           
                                dropFlag=true;
                                selected_item.setVisibility(View.INVISIBLE);
                            }
                            //Drop Image Here                       
                            selected_item.setLayoutParams(lp);
                            break;  
                        case MotionEvent.ACTION_UP:
                            //                      
                            touchFlag=false;
                            if(dropFlag==true)
                            {
                                dropFlag=false;
                            }
                            else
                            {
                                selected_item.setLayoutParams(imageParams);
                            }                       
                            break;
                        default:
                            break;
                        }
                    }else
                    {
                        System.err.println("Display Else Part ::->"+touchFlag);
                    }               
                    return true;
                }
            });

            image1.setOnTouchListener(this);
            image2.setOnTouchListener(this);
        }

        public boolean onTouch(View v, MotionEvent event) 
        {   
            switch (event.getActionMasked()) 
            {
            case MotionEvent.ACTION_DOWN:
                touchFlag=true;
                offset_x = (int) event.getX();
                offset_y = (int) event.getY();
                selected_item = v;
                imageParams=v.getLayoutParams();
                break;
            case MotionEvent.ACTION_UP:
                selected_item=null;
                touchFlag=false;
                break;
            default:
                break;
            }       
            return false;
        }
    }

After This create one class and Extend your main Layout like RelativeLayout

package info.tempDD;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

public class TouchInterceptor extends RelativeLayout {
    public TouchInterceptor(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        return super.onInterceptTouchEvent(ev);
    }

}

And the Main My Xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/ImgDrop"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:layout_marginTop="50dp"
        android:background="#FFFFFF" >
    </ImageView>

    <ImageView
        android:id="@+id/img"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/ic_launcher" >
    </ImageView>

    <ImageView
        android:id="@+id/img2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="@drawable/ic_launcher" >
    </ImageView>

</RelativeLayout>

ok now happy i done my job and also happy because i satisfied with my work i hope this will be help you. and the link which give me the way is below.

  • rxwen-blog-stuff
  • android-drag-and-drop-basic

Solution 2:

DragDropManager.class

package com.example.dragdrop;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.PopupWindow;

public class DragDropManager
{
    private static DragDropManager instance;
    private Activity mActivity;
    private List<View> dropzones;
    private Map<View, Integer> dropzonestates;
    private Map<View, DropZoneListener> dropzonelisteners;
    private PopupWindow popoup;
    private MotionEvent firstEvent;
    private Rect rect;
    private Object item;

    public static DragDropManager getInstance()
    {
        if (instance == null) instance = new DragDropManager();
        return instance;
    }

    private DragDropManager()
    {
    }

    public void init(Activity a)
    {
        mActivity = a;
        dropzones = new ArrayList<View>();
        dropzonelisteners = new HashMap<View, DropZoneListener>();
        dropzonestates = new HashMap<View, Integer>();
        rect = new Rect();
    }

    public void addDropZone(View zone, DropZoneListener zonelistener)
    {
        dropzones.add(zone);
        dropzonelisteners.put(zone, zonelistener);
        dropzonestates.put(zone, 0);
    }

    public void clearZones()
    {
        dropzones.clear();
        dropzonelisteners.clear();
        dropzonestates.clear();
    }

    public void clearZone(View zone)
    {
        dropzones.remove(zone);
        dropzonelisteners.remove(zone);
        dropzonestates.remove(zone);
    }

    private void checkDropZones(MotionEvent event)
    {
        boolean isOver;
        HashSet<DropZoneListener> listeners = new HashSet<DropZoneListener>(dropzonelisteners.values());

        for (View zone : dropzones)
        {
            int[] location = new int[2];
            zone.getLocationInWindow(location);
            zone.getDrawingRect(rect);
            rect.offset(location[0], location[1]);
            isOver = rect.contains((int) event.getRawX(), (int) event.getRawY());

            switch (dropzonestates.get(zone))
            {
                case 0:
                    if (isOver)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDragZoneEntered(zone, item); 
                        }
                        dropzonestates.put(zone, 1);
                    }

                    break;
                case 1:
                    if (!isOver)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDragZoneLeft(zone, item);    
                        }
                        dropzonestates.put(zone, 0);
                    }
                    else if (isOver && event.getAction()==MotionEvent.ACTION_UP)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDropped(zone, item); 
                        }
                        dropzonestates.put(zone, 0);
                    }
                    break;
            }
        }
    }

    public void startDragging(final View dragView, Object item)
    {
        this.item = item;
        // Copy view Bitmap (Clone Object visual)
        ImageView view = new ImageView(mActivity);
        view.measure(dragView.getWidth(), dragView.getHeight());

        Bitmap returnedBitmap = Bitmap.createBitmap(dragView.getWidth(), dragView.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        dragView.draw(canvas);

        view.setBackgroundDrawable(new BitmapDrawable(dragView.getResources(), returnedBitmap));

        // Set up Window
        popoup = new PopupWindow(view, dragView.getWidth(), dragView.getHeight());
        popoup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        // set window at position
        int[] location = new int[2];
        dragView.getLocationInWindow(location);
        popoup.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.NO_GRAVITY, location[0], location[1]);
        // Switch call Backs
        callbackDefault = mActivity.getWindow().getCallback();
        mActivity.getWindow().setCallback(callback);
    }

    private android.view.Window.Callback callbackDefault;

    private android.view.Window.Callback callback = new android.view.Window.Callback()
    {

        @Override
        public boolean dispatchGenericMotionEvent(MotionEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchKeyShortcutEvent(KeyEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent event)
        {
            checkDropZones(event);

            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                // popoup.update((int)event.getRawX(), (int)event.getRawY(), -1,
                // -1);
            }

            if (event.getAction() == MotionEvent.ACTION_MOVE)
            {
                if (firstEvent == null) firstEvent = MotionEvent.obtain(event);

                // Log.v("EVENT","X:"+event.getRawX() + " _X:" + location[0] +
                // " __X:" + firstEvent.getRawX());
                // Log.v("EVENT","Y:"+event.getRawY() + " _Y:" + location[1] +
                // " __Y:" + firstEvent.getRawY());

                float pos_x = event.getRawX() + (-popoup.getWidth() / 2);
                float pos_y = event.getRawY() + (-popoup.getHeight() / 2);

                popoup.update((int) pos_x, (int) pos_y, -1, -1);

            }

            if (event.getAction() == MotionEvent.ACTION_UP)
            {
                popoup.dismiss();
                mActivity.getWindow().setCallback(callbackDefault);
            }

            return false;
        }

        @Override
        public boolean dispatchTrackballEvent(MotionEvent event)
        {
            return false;
        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void onActionModeFinished(ActionMode mode)
        {
            // TODO Auto-generated method stub

        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void onActionModeStarted(ActionMode mode)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAttachedToWindow()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onContentChanged()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public View onCreatePanelView(int featureId)
        {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void onDetachedFromWindow()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onMenuOpened(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onPanelClosed(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onSearchRequested()
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams attrs)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onWindowFocusChanged(boolean hasFocus)
        {
            // TODO Auto-generated method stub

        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public ActionMode onWindowStartingActionMode(Callback callback)
        {
            // TODO Auto-generated method stub
            return null;
        }

    };

    public interface DropZoneListener
    {

        void OnDragZoneEntered(View zone, Object item);

        void OnDragZoneLeft(View zone, Object item);

        void OnDropped(View zone, Object item);

    }
}

MainActivity.class

package com.example.dragdrop;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.dragdrop.DragDropManager.DropZoneListener;

public class MainActivity extends Activity implements OnLongClickListener, OnTouchListener
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DragDropManager.getInstance().init(this);

        Button b1 = (Button) findViewById(R.id.button1);
        Button b2 = (Button) findViewById(R.id.button2);
        Button b3 = (Button) findViewById(R.id.button3);

        EditText et1 = (EditText) findViewById(R.id.editText1);
        TextView tv1 = (TextView) findViewById(R.id.textView1);

        Button b4 = (Button) findViewById(R.id.button4);
        Button b5 = (Button) findViewById(R.id.button5);
        Button b6 = (Button) findViewById(R.id.button6);

        b1.setOnTouchListener(this);
        b2.setOnLongClickListener(this);
        b3.setOnTouchListener(this);

        et1.setOnTouchListener(this);
        tv1.setOnTouchListener(this);

        DragDropManager.getInstance().addDropZone(b4, dropZoneListener1);
        DragDropManager.getInstance().addDropZone(b5, dropZoneListener1);
        DragDropManager.getInstance().addDropZone(b6, dropZoneListener1);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    DropZoneListener dropZoneListener1 = new DropZoneListener()
    {

        @Override
        public void OnDropped(View zone, Object item)
        {
            Log.v("ddddd","drop time");
            switch(zone.getId())
            {
                case R.id.button4:
                    if (item instanceof String) 
                        ((Button)zone).setText("DROP ITEM OK");
                    else    
                        ((Button)zone).setText("DROP ITEM ERR");

                    break;
                case R.id.button5:
                    ((Button)zone).setText("DROP");
                    break;
                case R.id.button6:
                    if (item instanceof Integer) 
                        ((Button)zone).setText("DROP ITEM OK");
                    else    
                        ((Button)zone).setText("DROP ITEM ERR");
                    break;
            }

        }

        @Override
        public void OnDragZoneLeft(View zone, Object item)
        {

            switch(zone.getId())
            {
                case R.id.button4:
                    ((Button)zone).setText("LEFT");
                    break;
                case R.id.button5:
                    ((Button)zone).setText("LEFT");
                    break;
                case R.id.button6:
                    ((Button)zone).setText("LEFT");
                    break;
            }
        }

        @Override
        public void OnDragZoneEntered(View zone, Object item)
        {
            switch(zone.getId())
            {
                case R.id.button4:
                    if (item instanceof String) 
                        ((Button)zone).setText("ENTER ITEM OK");
                    else    
                        ((Button)zone).setText("ENTER ITEM ERR");
                    break;
                case R.id.button5:
                    ((Button)zone).setText("ENTER");
                    break;
                case R.id.button6:
                    if (item instanceof Integer) 
                        ((Button)zone).setText("ENTER ITEM OK");
                    else    
                        ((Button)zone).setText("ENTER ITEM ERR");
                    break;
            }
        }
    };

    @Override
    public boolean onLongClick(View v)
    {
        DragDropManager.getInstance().startDragging(v, 0);
        return false;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        DragDropManager.getInstance().startDragging(v, "String");
        return false;
    }

}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="14dp"
        android:text="Click" />

    <Button
        android:id="@+id/button2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="29dp"
        android:text="Long" />

    <Button
        android:id="@+id/button3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button2"
        android:layout_below="@+id/button2"
        android:layout_marginTop="16dp"
        android:text="Click" />

    <Button
        android:id="@+id/button6"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignTop="@+id/button3"
        android:layout_marginLeft="39dp"
        android:layout_toRightOf="@+id/button3"
        android:text="Drop3" />

    <Button
        android:id="@+id/button5"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button4"
        android:layout_centerVertical="true"
        android:text="Drop2" />

    <Button
        android:id="@+id/button4"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@+id/button5"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="35dp"
        android:layout_marginRight="20dp"
        android:text="Drop1" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button3"
        android:layout_below="@+id/button3"
        android:layout_marginTop="17dp"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button6"
        android:layout_alignParentLeft="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

I have some inspiration from MobileAnarchyWidget but i improve some things.

As you can see I use PopupWindow for creating dragEfect even i clone visual part from draggable object. Also i dont have to use any part of layout. Simple put DragDropManager.class to your project. No changes are needed. No additional Resources. More zones can be hit at once if one zone full/partly cover another. You can drag anything what is at least view. I switching callback on Activity window so when you drag something nothing else have access to events. In this solution you never lost focus from Draggable and also when you pick UP finger from screen DragDrop will automaticaly end (Activity regain control for callbacks).

I dont have time to show you all combinations to use. But as you can see there is ony one DropZoneListener. You can use more but remember All listener are called and all changed Drag States are sended to each listener.

example: Dropzones D1,D2; Listener L1,L2;

if D1 or D2 changed L1(Dx) and L2(Dx)

if D1 and D2 changed L1(D1,D2) and L2(D1,D2)

But it is good because you know if it is dropped somewhere else. And i forget DragItem is Object so when is dropped you must resolve type of object. But this is also good because when you using fragments you never know what kind of data could be dragged.

In my solution i do check on object type level. If object is not supported by dragzone than you will know.