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.