Hola!
Con desarrollo para Android tienes que seguir la propia API de Android, puedes consultarla en
https://developer.android.com/guide/topics/ui/drag-drop.htmlPuedes guiarte por este ejemplo que te copio:
Partimos de 3 archivos xml para construir la vista, un layout principal “activity_drag.xml”, otro para definir un fondo, “shape.xml” y por último, otro para definir el fondo cuando arrastramos un elemento “shape_target.xml”.
Código de “activity_drag.xml”:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="vertical"
android:background="@drawable/shape"
>
<ImageView
android:id="@+id/imagen1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</LinearLayout>
<LinearLayout
android:id="@+id/right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="vertical"
android:background="@drawable/shape" >
<ImageView
android:id="@+id/imagen2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</LinearLayout>
</LinearLayout>
Este código es simple, tenemos dos LinearLayouts alineados horizontalmente con una imagen cada uno, en este caso la imagen por defecto del icono del app.
Si te fijas, los 2 layouts internos, en la propiedad background tienen un ‘@drawable/shape’, por lo que cogerá como fondo el fichero shape.xml, el cual se muestra aquí:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid
android:color="#0385B9"
/>
<stroke
android:width="2dp"
android:color="#FFF" />
<corners
android:bottomLeftRadius="7dp"
android:bottomRightRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
</shape>
Declaramos que la forma será un cuadrado, que tendrá color azul, un stroke de 2dp, que vendría a hacer las veces de un margen entre layouts, y por último, un borde redondeado.
Cabe destacar que puede haber otras maneras de definir nuestros fondos para un layout.
Por último, vamos a tener un “shape_target.xml” que se “activará” cuando agarremos una imagen para moverla, cuyo código es:
<?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="#000" />
<solid
android:color="#FFF"
/>
<corners
android:bottomLeftRadius="7dp"
android:bottomRightRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
</shape>
Lista la vista de nuestra app.
El código del manifest.xml, se podría decir que es el archivo donde irá la configuración de nuestra app:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dragdrop"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.dragdrop.DragActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Una de las cosas que más habría que tener en cuenta sería la versión mínima de nuestro sdk, en este ejemplo es la 16 debido a que algunas de las funciones utilizadas en el código están disponibles sólo a partir de esa versión.
Vamos al código Java:
package com.example.dragdrop;
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 {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag);
findViewById(R.id.imagen1).setOnTouchListener(new imgTouchListener());
findViewById(R.id.imagen2).setOnTouchListener(new imgTouchListener());
findViewById(R.id.left).setOnDragListener(new ContainerDragListener());
findViewById(R.id.right).setOnDragListener(new ContainerDragListener());
}
private class imgTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
/*ACTION_DOWN -> A pressed gesture has started, the motion contains the initial position*/
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
/*Creates an image that the system displays during the drag and drop operation. This is called a "drag shadow".*/
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
/*while the img is moving, the view is invisible, if we comment this line, the view 'will move' when we drop it*/
view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
}
private class ContainerDragListener 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:
/*change de background*/
v.setBackground(enterShape);
break;
case DragEvent.ACTION_DRAG_EXITED:
v.setBackground(normalShape);
break;
case DragEvent.ACTION_DROP:
// Dropped, reassign View to ViewGroup
View view = (View) event.getLocalState();
LinearLayout oldContainer = (LinearLayout) view.getParent();
oldContainer.removeView(view);
LinearLayout newContainer = (LinearLayout) v;
newContainer.addView(view);
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
v.setBackground(normalShape);
default:
break;
}
return true;
}
}
}
El método ‘onCreate’ es llamado al crear la app, en él obtenemos los layouts y les añadimos un evento ‘onDragListener’, y obtenemos las imagenes, a las cuales les añadimos el evento ‘onTouchListener’.
A continuación tenemos la clase imgTouchListener, de la cual se creará una instancia para el evento añadido a la imagen, en ella, simplemente ‘escuchamos’ que la acción llevada a cabo es la de ‘pulsar’ la imagen, en ese caso llevamos a cabo el proceso de cambio de layout.
Por otra parte, la clase ‘ContainerDragListener’ es la encargada de cambiar el fondo de los layouts cuando arrastramos la imagen, en esta clase, el evento más importante sería ‘ACTION_DROP’, que se produce cuando soltamos la imagen en el nuevo layout, cuando se produzca ese evento, lo que haremos será eliminar la imagen (view) del antiguo layout y añadirla al nuevo.
Saludos!