Android: trascina e rilascia

Il framework di trascinamento della selezione Android consente agli utenti di spostare i dati da una vista all'altra nel layout corrente utilizzando un gesto grafico di trascinamento della selezione. Come diAPI 11 è supportato il trascinamento della vista su altre viste o gruppi di viste. Il framework include i seguenti tre componenti importanti per supportare la funzionalità di trascinamento della selezione:

  • Drag event class.

  • Drag listeners.

  • Helper methods and classes.

Il processo di trascinamento della selezione

Ci sono fondamentalmente quattro passaggi o stati nel processo di trascinamento della selezione:

  • Started - Questo evento si verifica quando si inizia a trascinare un elemento in un layout, l'applicazione chiama il metodo startDrag () per dire al sistema di avviare un trascinamento. Gli argomenti all'interno del metodo startDrag () forniscono i dati da trascinare, i metadati per questi dati e un callback per disegnare l'ombra di trascinamento.

    Il sistema risponde prima richiamando la tua applicazione per ottenere un'ombra di trascinamento. Quindi visualizza l'ombreggiatura di trascinamento sul dispositivo.

    Successivamente, il sistema invia un evento di trascinamento con tipo di azione ACTION_DRAG_STARTED ai listener di eventi di trascinamento registrati per tutti gli oggetti Visualizza nel layout corrente.

    Per continuare a ricevere eventi di trascinamento, incluso un possibile evento di trascinamento, deve tornare un listener di eventi di trascinamento true, Se il listener di eventi di trascinamento restituisce false, non riceverà eventi di trascinamento per l'operazione corrente finché il sistema non invia un evento di trascinamento con tipo di azione ACTION_DRAG_ENDED.

  • Continuing- L'utente continua il trascinamento. Il sistema invia l'azione ACTION_DRAG_ENTERED seguita dall'azione ACTION_DRAG_LOCATION al listener di eventi di trascinamento registrato per la vista in cui entra il punto di trascinamento. L'ascoltatore può scegliere di modificare l'aspetto del suo oggetto View in risposta all'evento o può reagire evidenziandone la View.

    Il listener di eventi di trascinamento riceve un'azione ACTION_DRAG_EXITED dopo che l'utente ha spostato l'ombra di trascinamento fuori dal riquadro di delimitazione della vista.

  • Dropped- L'utente rilascia l'elemento trascinato all'interno del riquadro di delimitazione di una vista. Il sistema invia al listener dell'oggetto View un evento di trascinamento con tipo di azione ACTION_DROP.

  • Ended - Subito dopo il tipo di azione ACTION_DROP, il sistema invia un evento di trascinamento con il tipo di azione ACTION_DRAG_ENDED per indicare che l'operazione di trascinamento è terminata.

La classe DragEvent

Il DragEventrappresenta un evento inviato dal sistema in diversi momenti durante un'operazione di trascinamento. Questa classe fornisce poche costanti e metodi importanti che utilizziamo durante il processo di trascinamento / rilascio.

Costanti

Di seguito sono riportati tutti i numeri interi delle costanti disponibili come parte della classe DragEvent.

Sr.No. Costanti e descrizione
1

ACTION_DRAG_STARTED

Segnala l'inizio di un'operazione di trascinamento della selezione.

2

ACTION_DRAG_ENTERED

Segnala a una vista che il punto di trascinamento è entrato nel riquadro di delimitazione della vista.

3

ACTION_DRAG_LOCATION

Inviato a una vista dopo ACTION_DRAG_ENTERED se l'ombra di trascinamento è ancora all'interno del riquadro di delimitazione dell'oggetto Visualizza.

4

ACTION_DRAG_EXITED

Segnala che l'utente ha spostato l'ombra di trascinamento fuori dal riquadro di delimitazione della vista.

5

ACTION_DROP

Segnala a una vista che l'utente ha rilasciato l'ombra di trascinamento e il punto di trascinamento si trova all'interno del riquadro di delimitazione della vista.

6

ACTION_DRAG_ENDED

Segnala a una vista che l'operazione di trascinamento della selezione è terminata.

Metodi

Di seguito sono riportati alcuni metodi importanti e utilizzati più di frequente disponibili come parte della classe DragEvent.

Sr.No. Costanti e descrizione
1

int getAction()

Controlla il valore dell'azione di questo evento ..

2

ClipData getClipData()

Restituisce l'oggetto ClipData inviato al sistema come parte della chiamata a startDrag ().

3

ClipDescription getClipDescription()

Restituisce l'oggetto ClipDescription contenuto in ClipData.

4

boolean getResult()

Restituisce un'indicazione del risultato dell'operazione di trascinamento della selezione.

5

float getX()

Ottiene la coordinata X del punto di trascinamento.

6

float getY()

Ottiene la coordinata Y del punto di trascinamento.

7

String toString()

Restituisce una rappresentazione di stringa di questo oggetto DragEvent.

Ascolto per Drag Event

Se vuoi che una qualsiasi delle tue viste all'interno di un layout risponda all'evento di trascinamento, la tua vista viene implementata View.OnDragListener o configurazione onDragEvent(DragEvent)metodo di callback. Quando il sistema chiama il metodo o il listener, passa loro un oggetto DragEvent spiegato sopra. Puoi avere sia un listener che un metodo di callback per l'oggetto View. In tal caso, il sistema chiama prima il listener e quindi definisce il callback finché il listener restituisce true.

La combinazione del metodo onDragEvent (DragEvent) e View.OnDragListener è analoga alla combinazione delonTouchEvent() e View.OnTouchListener utilizzato con eventi di tocco nelle vecchie versioni di Android.

Avvio di un evento di trascinamento

Inizi con la creazione di un file ClipData e ClipData.Itemper i dati spostati. Come parte dell'oggetto ClipData , fornire i metadati archiviati in un fileClipDescriptionoggetto all'interno di ClipData. Per un'operazione di trascinamento della selezione che non rappresenta lo spostamento dei dati, potresti voler utilizzarenull invece di un oggetto reale.

Successivamente puoi estendere estendere View.DragShadowBuilderper creare un'ombra di trascinamento per trascinare la vista o semplicemente puoi usare View.DragShadowBuilder (Visualizza) per creare un'ombra di trascinamento predefinita della stessa dimensione dell'argomento Visualizza passato ad essa, con il punto di contatto centrato nell'ombra di trascinamento.

Esempio

L'esempio seguente mostra la funzionalità di un semplice Drag & Drop utilizzando View.setOnLongClickListener(), View.setOnTouchListener()e View.OnDragEventListener().

Passo Descrizione
1 Utilizzerai l'IDE di Android Studio per creare un'applicazione Android e chiamarla My Application in un pacchetto com.example.saira_000.myapplication .
2 Modificare il file src / MainActivity.java e aggiungere il codice per definire i listener di eventi, nonché i metodi di richiamata per l'immagine del logo utilizzata nell'esempio.
3 Copia l'immagine abc.png nelle cartelle res / drawable- * . È possibile utilizzare immagini con risoluzione diversa nel caso in cui si desideri fornirle per dispositivi diversi.
4 Modificare il file XML di layout res / layout / activity_main.xml per definire la visualizzazione predefinita delle immagini del logo.
5 Esegui l'applicazione per avviare l'emulatore Android e verifica il risultato delle modifiche apportate nell'applicazione.

Di seguito è riportato il contenuto del file di attività principale modificato src/MainActivity.java. Questo file può includere ciascuno dei metodi fondamentali del ciclo di vita.

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;
            }
         }
      });
   }
}

Di seguito sarà il contenuto di res/layout/activity_main.xml file -

Nel codice seguente abc indica il logo di 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>

Di seguito sarà il contenuto di res/values/strings.xml per definire due nuove costanti -

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

Di seguito è riportato il contenuto predefinito di 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>

Proviamo a eseguire il tuo My Applicationapplicazione. Presumo che tu abbia creato il tuoAVDdurante l'impostazione dell'ambiente. Per eseguire l'app da Android Studio, apri uno dei file di attività del progetto e fai clic sull'icona Esegui dalla barra degli strumenti. Android Studio installa l'app sul tuo AVD e la avvia e se tutto va bene con la configurazione e l'applicazione, verrà visualizzata la seguente finestra dell'emulatore:

Ora fai clic a lungo sul logo TutorialsPoint visualizzato e vedrai che l'immagine del logo si sposta leggermente dopo un clic di 1 secondo dalla sua posizione, è il momento in cui dovresti iniziare a trascinare l'immagine. Puoi trascinarlo sullo schermo e rilasciarlo in una nuova posizione.