Android — Drag and Drop (перетаскивание)


Платформа Android позволяет пользователям перемещать данные из одного View (представления) в другое представление в текущем макете с помощью графического жеста Drag and Drop (перетаскивания). По состоянию на API 11 поддерживается перетаскивание представления на другие представления или группы представлений. Фреймворк включает следующие три важных компонента для поддержки функции перетаскивания:

Процессы Drag and Drop

В основном процесс перетаскивания состоит из четырех этапов или состояний:

  • Started — это событие происходит, когда вы начинаете перетаскивать элемент в макете, ваше приложение вызывает startDrag () способ сообщить системе начать перетаскивание. Аргументы внутри метода startDrag () предоставляют данные для перетаскивания, метаданные для этих данных и обратный вызов для рисования тени перетаскивания.

    Система сначала отвечает обратным вызовом вашему приложению, чтобы получить тень от перетаскивания. Затем он отображает перетаскиваемую тень на устройстве.

    Затем система отправляет событие перетаскивания с типом действия ACTION_DRAG_STARTED в зарегистрированные прослушиватели событий перетаскивания для всех объектов View в текущем макете.

    Чтобы продолжить получение событий перетаскивания, включая возможное событие перетаскивания, прослушиватель событий перетаскивания должен вернуть true. Если прослушиватель событий перетаскивания возвращает false, он не будет получать события перетаскивания для текущей операции, пока система не отправит событие перетаскивания с типом действия ACTION_DRAG_ENDED.

  • Continuing — пользователь продолжает перетаскивание. Система отправляет действие ACTION_DRAG_ENTERED, за которым следует действие ACTION_DRAG_LOCATION, зарегистрированному прослушивателю событий перетаскивания для представления, в которое входит точка перетаскивания. Слушатель может выбрать изменение внешнего вида своего объекта View в ответ на событие или может отреагировать, выделив его View.

    Слушатель событий перетаскивания получает действие ACTION_DRAG_EXITED после того, как пользователь переместил тень перетаскивания за ограничивающую рамку представления.

  • Dropped — пользователь отпускает перетаскиваемый элемент в ограничивающей рамке представления. Система отправляет слушателю объекта View событие перетаскивания с типом действия ACTION_DROP.
  • Ended — сразу после действия ACTION_DROP система отправляет событие перетаскивания с типом действия ACTION_DRAG_ENDED, чтобы указать, что операция перетаскивания завершена.

Класс DragEvent

В DragEvent представляет событие, которое система отправляет в разное время во время операции перетаскивания. Этот класс предоставляет несколько констант и важных методов, которые мы используем в процессе перетаскивания.

Константы

Ниже приведены все целые числа констант, доступные как часть класса DragEvent.

Константы и описание
1ACTION_DRAG_STARTED

Сигнализирует о начале операции перетаскивания.

2ACTION_DRAG_ENTERED

Сигналы к представлению о том, что точка перетаскивания вошла в ограничивающую рамку представления.

3ACTION_DRAG_LOCATION

Отправляется в представление после ACTION_DRAG_ENTERED, если тень перетаскивания все еще находится в ограничивающей рамке объекта View.

4ACTION_DRAG_EXITED

Сигнализирует, что пользователь переместил тень перетаскивания за ограничивающую рамку представления.

5ACTION_DROP

Сигналы к представлению View о том, что пользователь отпустил тень перетаскивания, и точка перетаскивания находится в пределах ограничивающей рамки представления.

6ACTION_DRAG_ENDED

Сообщает View, что операция перетаскивания завершена.

Методы

Ниже приведены несколько важных и наиболее часто используемых методов, доступных как часть класса DragEvent.

Методы и описание
1int getAction ()

Проверяет значение действия этого события.

2ClipData getClipData ()

Возвращает объект ClipData, отправленный в систему как часть вызова startDrag ().

3ClipDescription getClipDescription ()

Возвращает объект ClipDescription, содержащийся в ClipData.

4boolean getResult ()

Возвращает индикацию результата операции перетаскивания.

5float getX()

Получает координату X точки перетаскивания.

6float getY()

Получает координату Y точки перетаскивания.

7String toString()

Возвращает строковое представление этого объекта DragEvent.

Прослушивание события перетаскивания

Если вы хотите, чтобы какое-либо из ваших представлений в макете отвечало на событие перетаскивания, тогда ваше представление либо реализует View.OnDragListener или настроить onDragEvent (DragEvent) метод обратного вызова. Когда система вызывает метод или слушателя, она передает им объект DragEvent, описанный выше. У вас может быть как слушатель, так и метод обратного вызова для объекта View. Если это происходит, система сначала вызывает слушателя, а затем определяет обратный вызов, пока слушатель возвращает истину.

Сочетание onDragEvent (DragEvent) метод и View.OnDragListener аналогично комбинации onTouchEvent () и View.OnTouchListener используется с событиями касания в старых версиях Android.

Запуск события перетаскивания

Вы начинаете с создания ClipData и ClipData.Item для перемещаемых данных. В рамках ClipData объект, предоставить метаданные, которые хранятся в ClipDescription объект в ClipData. Для операции перетаскивания, которая не представляет перемещение данных, вы можете использовать null вместо реального объекта.

Затем вы можете продлить расширение View.DragShadowBuilder для создания тени для перетаскивания вида или просто вы можете использовать View.DragShadowBuilder (Просмотр) для создания тени перетаскивания по умолчанию того же размера, что и переданный ей аргумент View, с точкой касания в центре тени перетаскивания.

Пример

В следующем примере показана функциональность простого перетаскивания с использованием View.setOnLongClickListener (), View.setOnTouchListener () и View.OnDragEventListener ().

ШагОписание
1Вы будете использовать Android studio IDE для создания Android-приложения и назовете его как Мое приложение под пакет com.example.saira_000.myapplication.
2Изменить src / MainActivity.java файл и добавьте код для определения прослушивателей событий, а также методы обратного вызова для изображения логотипа, используемого в примере.
3Скопируйте изображение abc.png в res / drawable папку. Вы можете использовать изображения с разным разрешением, если хотите предоставить их для разных устройств.
4Изменить XML-файл макета res / layout / activity_main.xml для определения вида изображений логотипов по умолчанию.
5Запустите приложение, чтобы запустить эмулятор Android и проверить результат изменений, внесенных в приложение.

Ниже приводится содержание измененного файла основной деятельности
src / MainActivity.java. Этот файл может включать каждый из основных методов жизненного цикла.

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");
               
               // Ничего не делать
               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");
               
               // Ничего не делать
               break;
               
               case DragEvent.ACTION_DROP:
               Log.d(msg, "ACTION_DROP event");
               
               // Ничего не делать
               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;
            }
         }
      });
   }
}

Ниже будет содержание res / layout / activity_main.xml файл —

В следующем коде abc обозначает логотип 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="https://www.tutorialspoint.com/android/@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>

Ниже будет содержание res / values ​​/ strings.xml чтобы определить две новые константы

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

Ниже приводится содержимое по умолчанию 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>

Попробуем запустить приложение Мое приложение. Я полагаю, вы создали свой AVD при настройке среды. Чтобы запустить приложение из Android Studio, откройте один из файлов активности вашего проекта и нажмите «Выполнить». Значок Eclipse Run значок на панели инструментов. Студия Android устанавливает приложение на ваш AVD и запускает его, и если все в порядке с вашей настройкой и приложением, оно отобразит следующее окно эмулятора.

Android перетаскивание

Теперь нажмите и удерживайте отображаемый логотип TutorialsPoint, и вы увидите, что изображение логотипа немного сдвинется после длительного щелчка в течение 1 секунды со своего места, это время, когда вы должны начать перетаскивать изображение. Вы можете перетащить его по экрану и бросить в новом месте.

Переход Android в новое место

Поделись с друзьями:

Оставьте комментарий