Android - arrastar e soltar

A estrutura de arrastar / soltar do Android permite que seus usuários movam dados de uma Visualização para outra Visualização no layout atual usando um gesto gráfico de arrastar e soltar. A partir deAPI 11 arrastar e soltar de visualização em outras visualizações ou grupos de visualização é suportado. A estrutura inclui os seguintes três componentes importantes para suportar a funcionalidade de arrastar e soltar -

  • Drag event class.

  • Drag listeners.

  • Helper methods and classes.

O processo de arrastar / soltar

Existem basicamente quatro etapas ou estados no processo de arrastar e soltar -

  • Started - Este evento ocorre quando você começa a arrastar um item em um layout, seu aplicativo chama o método startDrag () para dizer ao sistema para iniciar um arrastar. Os argumentos dentro do método startDrag () fornecem os dados a serem arrastados, metadados para esses dados e um retorno de chamada para desenhar a sombra de arrasto.

    O sistema primeiro responde ligando de volta para seu aplicativo para obter uma sombra de arrasto. Em seguida, exibe a sombra de arrasto no dispositivo.

    Em seguida, o sistema envia um evento de arrastar com o tipo de ação ACTION_DRAG_STARTED para os ouvintes de evento de arrastar registrados para todos os objetos de Visualização no layout atual.

    Para continuar a receber eventos de arrastar, incluindo um possível evento de soltar, um ouvinte de evento de arrastar deve retornar true, Se o ouvinte de evento de arrastar retornar falso, ele não receberá eventos de arrastar para a operação atual até que o sistema envie um evento de arrastar com tipo de ação ACTION_DRAG_ENDED.

  • Continuing- O usuário continua a arrastar. O sistema envia a ação ACTION_DRAG_ENTERED seguida pela ação ACTION_DRAG_LOCATION para o ouvinte de evento de arrastar registrado para a Visualização onde o ponto de arrastar entra. O ouvinte pode escolher alterar a aparência de seu objeto de Visualização em resposta ao evento ou pode reagir destacando sua Visualização.

    O ouvinte de evento de arrastar recebe uma ação ACTION_DRAG_EXITED depois que o usuário move a sombra de arrastar para fora da caixa delimitadora da Visualização.

  • Dropped- O usuário libera o item arrastado dentro da caixa delimitadora de uma Visualização. O sistema envia ao listener do objeto View um evento de arrastar com o tipo de ação ACTION_DROP.

  • Ended - Logo após o tipo de ação ACTION_DROP, o sistema envia um evento de arrastar com tipo de ação ACTION_DRAG_ENDED para indicar que a operação de arrastar terminou.

A classe DragEvent

o DragEventrepresenta um evento enviado pelo sistema várias vezes durante uma operação de arrastar e soltar. Esta classe fornece algumas constantes e métodos importantes que usamos durante o processo de arrastar / soltar.

Constantes

A seguir estão todos os inteiros constantes disponíveis como parte da classe DragEvent.

Sr. Não. Constantes e Descrição
1

ACTION_DRAG_STARTED

Sinaliza o início de uma operação de arrastar e soltar.

2

ACTION_DRAG_ENTERED

Sinaliza para uma vista que o ponto de arrasto entrou na caixa delimitadora da vista.

3

ACTION_DRAG_LOCATION

Enviado para uma Visualização após ACTION_DRAG_ENTERED se a sombra de arrasto ainda estiver dentro da caixa delimitadora do objeto de Visualização.

4

ACTION_DRAG_EXITED

Sinaliza que o usuário moveu a sombra de arrasto para fora da caixa delimitadora da Visualização.

5

ACTION_DROP

Sinaliza para uma visualização que o usuário liberou a sombra de arrasto e o ponto de arrastar está dentro da caixa delimitadora da visualização.

6

ACTION_DRAG_ENDED

Sinaliza para uma vista que a operação de arrastar e soltar foi concluída.

Métodos

A seguir estão alguns métodos importantes e usados ​​com mais frequência disponíveis como parte da classe DragEvent.

Sr. Não. Constantes e Descrição
1

int getAction()

Inspecione o valor da ação deste evento.

2

ClipData getClipData()

Retorna o objeto ClipData enviado ao sistema como parte da chamada para startDrag ().

3

ClipDescription getClipDescription()

Retorna o objeto ClipDescription contido em ClipData.

4

boolean getResult()

Retorna uma indicação do resultado da operação de arrastar e soltar.

5

float getX()

Obtém a coordenada X do ponto de arrasto.

6

float getY()

Obtém a coordenada Y do ponto de arrasto.

7

String toString()

Retorna uma representação de string deste objeto DragEvent.

Ouvindo o evento de arrastar

Se você quiser que qualquer uma das suas visualizações dentro de um Layout responda o evento Arrastar, então a sua visualização implementa View.OnDragListener ou configuração onDragEvent(DragEvent)método de retorno de chamada. Quando o sistema chama o método ou ouvinte, ele passa para eles um objeto DragEvent explicado acima. Você pode ter um ouvinte e um método de retorno de chamada para o objeto View. Se isso ocorrer, o sistema primeiro chama o ouvinte e, em seguida, define o retorno de chamada, desde que o ouvinte retorne verdadeiro.

A combinação do método onDragEvent (DragEvent) e View.OnDragListener é análoga à combinação doonTouchEvent() e View.OnTouchListener usado com eventos de toque em versões antigas do Android.

Iniciando um evento de arrasto

Você começa criando um ClipData e ClipData.Itempara os dados que estão sendo movidos. Como parte do objeto ClipData , forneça metadados que são armazenados em umClipDescriptionobjeto dentro do ClipData. Para uma operação de arrastar e soltar que não representa o movimento de dados, você pode querer usarnull em vez de um objeto real.

Em seguida, você pode estender estender View.DragShadowBuilderpara criar uma sombra de arrasto para arrastar a visualização ou simplesmente você pode usar View.DragShadowBuilder (View) para criar uma sombra de arrasto padrão que é do mesmo tamanho que o argumento View passado para ela, com o ponto de toque centralizado na sombra de arrasto.

Exemplo

O exemplo a seguir mostra a funcionalidade de um simples Arrastar e Soltar usando View.setOnLongClickListener(), View.setOnTouchListener()e View.OnDragEventListener().

Degrau Descrição
1 Você usará o Android Studio IDE para criar um aplicativo Android e nomeá-lo como Meu aplicativo no pacote com.example.saira_000.myapplication .
2 Modifique o arquivo src / MainActivity.java e adicione o código para definir ouvintes de eventos, bem como métodos de retorno de chamada para a imagem do logotipo usada no exemplo.
3 Copie a imagem abc.png nas pastas res / drawable- * . Você pode usar imagens com resoluções diferentes, caso deseje fornecê-las para dispositivos diferentes.
4 Modifique o arquivo XML de layout res / layout / activity_main.xml para definir a visualização padrão das imagens do logotipo.
5 Execute o aplicativo para iniciar o emulador Android e verifique o resultado das alterações feitas no aplicativo.

A seguir está o conteúdo do arquivo de atividade principal modificado src/MainActivity.java. Este arquivo pode incluir cada um dos métodos fundamentais do ciclo de vida.

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

A seguir estará o conteúdo de res/layout/activity_main.xml arquivo -

No código a seguir, abc indica o logotipo 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>

A seguir estará o conteúdo de res/values/strings.xml para definir duas novas constantes -

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

A seguir está o conteúdo padrão 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>

Vamos tentar executar o seu My Applicationinscrição. Suponho que você tenha criado o seuAVDao fazer a configuração do ambiente. Para executar o aplicativo do Android Studio, abra um dos arquivos de atividade do seu projeto e clique no ícone Executar na barra de ferramentas. O Android Studio instala o aplicativo em seu AVD e o inicia e se tudo estiver bem com sua configuração e aplicativo, ele será exibido a seguir a janela do emulador -

Agora, clique longamente no logotipo do TutorialsPoint exibido e você verá que a imagem do logotipo se move um pouco após um clique de 1 segundo de seu lugar, é o momento em que você deve começar a arrastar a imagem. Você pode arrastá-lo pela tela e soltá-lo em um novo local.