How to implement Drag and Drop in Android 2.2?

I am trying to develop an Android application where the user needs to be able to drag and drop images from one grid cell to another. To implement this, I need the Drag and Drop API, which was introduced in Android 3.0, but my app needs to work in Android 2.2. So, is there a way to implement this using Touch events? If so, please provide me with a code snippet or any link that briefly describes it.

+2


source to share


4 answers


TouchEvent: TouchDown → LockItemOnTouchPoint

FollowTouchDirections → UpdateItemPosition

TouchEvent: TouchUp → LockItemPosition



-3


source


Hi after a long time, get success by doing drag and drop in android 2.2

here i give my code which gives you 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 that 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 i'm happy i did my job and also happy because i'm happy with my job. Hope this helps you. and the link that gives me the way is below.

+15


source


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 am improving some things.

As you can see, I am using PopupWindow to create dragEfect, even I am cloning the visual from the dragged object. Also I don't need to use any part of the layout. Easy transfer of DragDropManager.class to your project. No changes required. No additional resources required. In case one zone is filled / partially covered by another, you can press several zones at once. You can drag and drop anything, at least on the view. I am switching the callback to the Activity window, so when you drag and drop something, something else doesn't have access to events. In this solution, you never lost focus from Draggable, and also when you select UP finger from the screen, DragDrop exits automatically (Activity regains control for callbacks).

I don't have time to show you all the combinations. But as you can see there is one single DropZoneListener. You can use more, but remember that all listeners are called and all changed drag states are passed to each listener.

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

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

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

But that's good, because you know if it fell somewhere else. And I forgot that DragItem is an Object, so when casting you have to resolve to the type of the object. But it's also good, because when you use slices, you never know what data to drag and drop.

In my solution, I check the object type level. If the object is not supported by dragzone, you know.

+3


source


view.setOnTouchListener (new View.OnTouchListener () {

        public boolean onTouch(View v, MotionEvent me) {


            if (me.getAction() == MotionEvent.ACTION_MOVE) {


                v.setX(me.getRawX() - (v.getWidth() / 2));
                v.setY(me.getRawY() - (float)(v.getHeight()* 1.5 / 2));

            }

            return true;
        }
    }

      

);

+2


source







All Articles