Developpez.com

Une très vaste base de connaissances en informatique avec
plus de 100 FAQ et 10 000 réponses à vos questions

Tutoriel sur l'utilisation du Drag and Drop avec Android

Cet article va vous montrer comment utiliser les opérations de Drag and Drop sous Android.

NDT : la traduction française « glisser et déposer » du concept « Drag and Drop » en anglais n'a pas été utilisée dans cet article.

Les commentaires et les suggestions d'amélioration sont les bienvenus, alors, après votre lecture, n'hésitez pas. Commentez Donner une note à l'article (5).

Article lu   fois.

Les deux auteur et traducteur

Site personnel

Traducteur : Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Drag and Drop avec Android

1-1. Comment faire ?

Depuis Android version 4.0, le drag and drop des vues est supporté. Vous enregistrez un écouteur (listener) sur la vue qui peut être source du drag et vous définissez les autres vues comme destinations potentielles (ou drop zones).

1-2. Implémentation

Pour faire cela, il faut enregistrer un écouteur sur la vue avec OnTouchListener ou OnLongClickListener.

Dans cette méthode, vous construisez un objet du type ClipData. Cet objet peut être utilisé pour contenir des données à passer aux vues définies comme drop zones.

L'objet DragShadowBuilder vous permet de spécifier le look de l'opération drag. En général, vous passez directement en paramètre la vue qui va être montrée pour l'opération drag.

 
Sélectionnez
// Assign the touch listener to your view which you want to move
findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener());

// This defines your touch listener
private final class MyTouchListener implements OnTouchListener {
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
      ClipData data = ClipData.newPlainText("", "");
      DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
      view.startDrag(data, shadowBuilder, view, 0);
      view.setVisibility(View.INVISIBLE);
      return true;
    } else {
    return false;
    }
  }
}

Les vues qui sont utilisées comme une zone de drop possèdent un objet OnDragListener attribué par la méthode setOnDragListener. Dans l'objet OnDragListener, vous pouvez récupérer les événements et réagir en conséquence.

 
Sélectionnez
findViewById(R.id.bottomright).setOnDragListener(new MyDragListener());

class MyDragListener 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:
      v.setBackgroundDrawable(enterShape);
      break;
    case DragEvent.ACTION_DRAG_EXITED:        
      v.setBackgroundDrawable(normalShape);
      break;
    case DragEvent.ACTION_DROP:
      // Dropped, reassign View to ViewGroup
      View view = (View) event.getLocalState();
      ViewGroup owner = (ViewGroup) view.getParent();
      owner.removeView(view);
      LinearLayout container = (LinearLayout) v;
      container.addView(view);
      view.setVisibility(View.VISIBLE);
      break;
    case DragEvent.ACTION_DRAG_ENDED:
      v.setBackgroundDrawable(normalShape);
      default:
      break;
    }
    return true;
  }
}

2. Exercice

2-1. Création du projet

Créez un nouveau projet nommé de.vogella.android.draganddrop avec une activité nommée DragActivity.

2-2. Création des « drawable » XML 

Nous allons utiliser des objets XML « drawables » dans cet exemple.

Créez le répertoire « drawable » dans celui des ressources « res ». Créez le fichier « shape.xml » suivant dans ce répertoire :

 
Sélectionnez
<?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="#FFFFFFFF" />

    <gradient
        android:angle="225"
        android:endColor="#DD2ECCFA"
        android:startColor="#DD000000" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape>

Créez le fichier « shape_droptarget.xml » dans le répertoire « drawable » :

 
Sélectionnez
<?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="#FFFF0000" />

    <gradient
        android:angle="225"
        android:endColor="#DD2ECCFA"
        android:startColor="#DD000000" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />

</shape>

2-3. L'activité et son aspect

Modifiez l'aspect de votre activité en utilisant le code suivant :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2"
    android:columnWidth="300dp"
    android:orientation="vertical"
    android:rowCount="2"
    android:stretchMode="columnWidth" >

    <LinearLayout
        android:id="@+id/topleft"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="0"
        android:layout_row="0"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/topright"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="1"
        android:layout_row="0"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomleft"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="0"
        android:layout_row="1"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomright"
        android:layout_width="160dp"
        android:layout_height="200dp"
        android:layout_column="1"
        android:layout_row="1"
        android:background="@drawable/shape" >

        <ImageView
            android:id="@+id/myimage4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_column="0"
            android:layout_row="0"
            android:src="@drawable/ic_launcher" />
    </LinearLayout>

</GridLayout>

Modifiez le source de votre activité en utilisant le code suivant :

 
Sélectionnez
package de.vogella.android.draganddrop;

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 {
  
/** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener());
    findViewById(R.id.myimage2).setOnTouchListener(new MyTouchListener());
    findViewById(R.id.myimage3).setOnTouchListener(new MyTouchListener());
    findViewById(R.id.myimage4).setOnTouchListener(new MyTouchListener());
    findViewById(R.id.topleft).setOnDragListener(new MyDragListener());
    findViewById(R.id.topright).setOnDragListener(new MyDragListener());
    findViewById(R.id.bottomleft).setOnDragListener(new MyDragListener());
    findViewById(R.id.bottomright).setOnDragListener(new MyDragListener());

  }

  private final class MyTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
      if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
        ClipData data = ClipData.newPlainText("", "");
        DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
        view.startDrag(data, shadowBuilder, view, 0);
        view.setVisibility(View.INVISIBLE);
        return true;
      } else {
        return false;
      }
    }
  }

  class MyDragListener 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:
        v.setBackgroundDrawable(enterShape);
        break;
      case DragEvent.ACTION_DRAG_EXITED:
        v.setBackgroundDrawable(normalShape);
        break;
      case DragEvent.ACTION_DROP:
        // Dropped, reassign View to ViewGroup
        View view = (View) event.getLocalState();
        ViewGroup owner = (ViewGroup) view.getParent();
        owner.removeView(view);
        LinearLayout container = (LinearLayout) v;
        container.addView(view);
        view.setVisibility(View.VISIBLE);
        break;
      case DragEvent.ACTION_DRAG_ENDED:
        v.setBackgroundDrawable(normalShape);
      default:
        break;
      }
      return true;
    }
  }
}

Si vous lancez votre activité, vous devrez être capable de faire un drag des images vers un autre conteneur.

3. Quelques liens

5. Remerciements

Nous remercions l'auteur, Lars Vogel, de nous avoir aimablement autorisé à publier son article. Cet article est une traduction autorisée dont le texte original peut être trouvé sur vogella.com. Nous remercions aussi ram-0000 pour sa traduction, Feanorin pour sa relecture technique ainsi que milkoseck pour sa relecture orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Lars Vogel et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.