Android - Glisser-déposer

Le cadre de glisser / déposer Android permet à vos utilisateurs de déplacer des données d'une vue à une autre dans la mise en page actuelle à l'aide d'un geste graphique de glisser-déposer. À partir deAPI 11 le glisser-déposer de la vue sur d'autres vues ou groupes de vues est pris en charge.Le cadre comprend les trois composants importants suivants pour prendre en charge la fonctionnalité glisser-déposer:

  • Drag event class.

  • Drag listeners.

  • Helper methods and classes.

Le processus de glisser / déposer

Il y a essentiellement quatre étapes ou états dans le processus de glisser-déposer -

  • Started - Cet événement se produit lorsque vous commencez à faire glisser un élément dans une mise en page, votre application appelle la méthode startDrag () pour indiquer au système de démarrer un glisser. Les arguments de la méthode startDrag () fournissent les données à faire glisser, les métadonnées de ces données et un rappel pour dessiner l'ombre de glissement.

    Le système répond d'abord en rappelant votre application pour obtenir une ombre de glissement. Il affiche ensuite l'ombre de glissement sur l'appareil.

    Ensuite, le système envoie un événement de glissement avec le type d'action ACTION_DRAG_STARTED aux écouteurs d'événements de glissement enregistrés pour tous les objets View de la présentation actuelle.

    Pour continuer à recevoir des événements de glissement, y compris un éventuel événement de dépôt, un écouteur d'événements de glissement doit retourner true, Si l'écouteur d'événements de glissement renvoie false, il ne recevra pas d'événements de glissement pour l'opération en cours jusqu'à ce que le système envoie un événement de glissement avec le type d'action ACTION_DRAG_ENDED.

  • Continuing- L'utilisateur continue le glisser. Le système envoie l'action ACTION_DRAG_ENTERED suivie de l'action ACTION_DRAG_LOCATION à l'écouteur d'événements de glissement enregistré pour la vue dans laquelle le point de glissement entre. L'auditeur peut choisir de modifier l'apparence de son objet View en réponse à l'événement ou peut réagir en mettant en évidence sa vue.

    L'écouteur d'événements de glissement reçoit une action ACTION_DRAG_EXITED une fois que l'utilisateur a déplacé l'ombre de glissement en dehors du cadre de délimitation de la vue.

  • Dropped- L'utilisateur libère l'élément glissé dans le cadre de délimitation d'une vue. Le système envoie à l'écouteur de l'objet View un événement glisser avec le type d'action ACTION_DROP.

  • Ended - Juste après le type d'action ACTION_DROP, le système envoie un événement de glissement avec le type d'action ACTION_DRAG_ENDED pour indiquer que l'opération de glissement est terminée.

La classe DragEvent

le DragEventreprésente un événement envoyé par le système à différents moments au cours d'une opération de glisser-déposer. Cette classe fournit quelques constantes et méthodes importantes que nous utilisons pendant le processus de glisser / déposer.

Constantes

Voici tous les nombres entiers constants disponibles dans le cadre de la classe DragEvent.

N ° Sr. Constantes et description
1

ACTION_DRAG_STARTED

Signale le début d'une opération de glisser-déposer.

2

ACTION_DRAG_ENTERED

Signale à une vue que le point de glissement est entré dans le cadre de délimitation de la vue.

3

ACTION_DRAG_LOCATION

Envoyé à une vue après ACTION_DRAG_ENTERED si l'ombre de glissement se trouve toujours dans le cadre de délimitation de l'objet View.

4

ACTION_DRAG_EXITED

Signale que l'utilisateur a déplacé l'ombre de glissement en dehors du cadre de délimitation de la vue.

5

ACTION_DROP

Signale à une vue que l'utilisateur a libéré l'ombre de glissement et que le point de glissement se trouve dans le cadre de délimitation de la vue.

6

ACTION_DRAG_ENDED

Signale à une vue que l'opération de glisser-déposer est terminée.

Méthodes

Voici quelques méthodes importantes et les plus fréquemment utilisées disponibles dans le cadre de la classe DragEvent.

N ° Sr. Constantes et description
1

int getAction()

Inspectez la valeur d'action de cet événement.

2

ClipData getClipData()

Renvoie l'objet ClipData envoyé au système dans le cadre de l'appel à startDrag ().

3

ClipDescription getClipDescription()

Renvoie l'objet ClipDescription contenu dans ClipData.

4

boolean getResult()

Renvoie une indication du résultat de l'opération de glisser-déposer.

5

float getX()

Obtient la coordonnée X du point de glissement.

6

float getY()

Obtient la coordonnée Y du point de glissement.

sept

String toString()

Renvoie une représentation sous forme de chaîne de cet objet DragEvent.

Écoute de l'événement Drag

Si vous souhaitez que l'une de vos vues dans une mise en page réponde à l'événement Drag, votre vue implémente soit View.OnDragListener ou configuration onDragEvent(DragEvent)méthode de rappel. Lorsque le système appelle la méthode ou l'écouteur, il leur transmet un objet DragEvent expliqué ci-dessus. Vous pouvez avoir à la fois un écouteur et une méthode de rappel pour l'objet View. Si cela se produit, le système appelle d'abord l'écouteur, puis le rappel défini tant que l'écouteur renvoie true.

La combinaison de la méthode onDragEvent (DragEvent) et de View.OnDragListener est analogue à la combinaison deonTouchEvent() et View.OnTouchListener utilisé avec les événements tactiles dans les anciennes versions d'Android.

Démarrer un événement de glissement

Vous commencez par créer un ClipData et ClipData.Itempour les données déplacées. Dans le cadre de l' objet ClipData , fournissez des métadonnées qui sont stockées dans unClipDescriptionobjet dans ClipData. Pour une opération de glisser-déposer qui ne représente pas le mouvement des données, vous pouvez utilisernull au lieu d'un objet réel.

Ensuite, vous pouvez étendre l'extension View.DragShadowBuilderpour créer une ombre de glissement pour faire glisser la vue ou tout simplement vous pouvez utiliser View.DragShadowBuilder (Vue) pour créer une ombre de glissement par défaut de la même taille que l'argument Vue qui lui est passé, avec le point de contact centré dans l'ombre de glissement.

Exemple

L'exemple suivant montre la fonctionnalité d'un simple glisser-déposer en utilisant View.setOnLongClickListener(), View.setOnTouchListener()et View.OnDragEventListener().

Étape La description
1 Vous utiliserez l'IDE de studio Android pour créer une application Android et la nommerez My Application sous un package com.example.saira_000.myapplication .
2 Modifiez le fichier src / MainActivity.java et ajoutez le code pour définir les écouteurs d'événements ainsi qu'une méthode de rappel pour l'image du logo utilisée dans l'exemple.
3 Copiez l'image abc.png dans les dossiers res / drawable- * . Vous pouvez utiliser des images avec une résolution différente au cas où vous souhaiteriez les fournir pour différents appareils.
4 Modifiez le fichier XML de mise en page res / layout / activity_main.xml pour définir la vue par défaut des images du logo.
5 Exécutez l'application pour lancer l'émulateur Android et vérifier le résultat des modifications effectuées dans l'application.

Voici le contenu du fichier d'activité principal modifié src/MainActivity.java. Ce fichier peut inclure chacune des méthodes fondamentales du cycle de vie.

package com.example.saira_000.myapplication;

import android.app.Activity;

import android.content.ClipData;
import android.content.ClipDescription;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;

import android.view.DragEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;

import android.widget.ImageView;
import android.widget.RelativeLayout;


public class MainActivity extends Activity {
   ImageView img;
   String msg;
   private android.widget.RelativeLayout.LayoutParams layoutParams;
   
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      img=(ImageView)findViewById(R.id.imageView);
      
      img.setOnLongClickListener(new View.OnLongClickListener() {
         @Override
         public boolean onLongClick(View v) {
            ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
            String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
            
            ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(img);
            
            v.startDrag(dragData,myShadow,null,0);
            return true;
         }
      });
      
      img.setOnDragListener(new View.OnDragListener() {
         @Override
         public boolean onDrag(View v, DragEvent event) {
            switch(event.getAction()) {
               case DragEvent.ACTION_DRAG_STARTED:
               layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_STARTED");
               
               // Do nothing
               break;
               
               case DragEvent.ACTION_DRAG_ENTERED:
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
               int x_cord = (int) event.getX();
               int y_cord = (int) event.getY();
               break;
               
               case DragEvent.ACTION_DRAG_EXITED :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
               x_cord = (int) event.getX();
               y_cord = (int) event.getY();
               layoutParams.leftMargin = x_cord;
               layoutParams.topMargin = y_cord;
               v.setLayoutParams(layoutParams);
               break;
               
               case DragEvent.ACTION_DRAG_LOCATION  :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
               x_cord = (int) event.getX();
               y_cord = (int) event.getY();
               break;
               
               case DragEvent.ACTION_DRAG_ENDED   :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENDED");
               
               // Do nothing
               break;
               
               case DragEvent.ACTION_DROP:
               Log.d(msg, "ACTION_DROP event");
               
               // Do nothing
               break;
               default: break;
            }
            return true;
         }
      });
      
      img.setOnTouchListener(new View.OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
               ClipData data = ClipData.newPlainText("", "");
               View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(img);
               
               img.startDrag(data, shadowBuilder, img, 0);
               img.setVisibility(View.INVISIBLE);
               return true;
            } else {
               return false;
            }
         }
      });
   }
}

Voici le contenu de res/layout/activity_main.xml fichier -

Dans le code suivant abc indique le logo de tutorialspoint.com
<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" 
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin" 
   tools:context=".MainActivity">
   
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Drag and Drop Example"
      android:id="@+id/textView"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />
      
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials Point"
      android:id="@+id/textView2"
      android:layout_below="@+id/textView"
      android:layout_centerHorizontal="true"
      android:textSize="30dp"
      android:textColor="#ff14be3c" />>
      
   <ImageView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageView"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView2"
      android:layout_alignRight="@+id/textView2"
      android:layout_alignEnd="@+id/textView2"
      android:layout_alignLeft="@+id/textView2"
      android:layout_alignStart="@+id/textView2" />

</RelativeLayout>

Voici le contenu de res/values/strings.xml pour définir deux nouvelles constantes -

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">My Application</string>
</resources>

Voici le contenu par défaut de AndroidManifest.xml -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.saira_000.myapplication" >
      
   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      
      <activity
         android:name=".MainActivity"
         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>

Essayons d'exécuter votre My Applicationapplication. Je suppose que vous avez créé votreAVDlors de la configuration de l'environnement. Pour exécuter l'application à partir d'Android Studio, ouvrez l'un des fichiers d'activité de votre projet et cliquez sur l' icône Exécuter dans la barre d'outils. Le studio Android installe l'application sur votre AVD et le démarre et si tout va bien avec votre configuration et votre application, il affichera la fenêtre Emulator suivante -

Maintenant, faites un clic long sur le logo TutorialsPoint affiché et vous verrez que l'image du logo bouge un peu après un clic long de 1 seconde depuis sa place, c'est le moment où vous devriez commencer à faire glisser l'image. Vous pouvez le faire glisser sur l'écran et le déposer à un nouvel emplacement.