كود السحب والإفلات في برمجة الأندرويد Android Drag and Drop

كود السحب والإفلات في برمجة الأندرويد

 Android Drag and Drop


كود السحب والإفلات في برمجة الأندرويد Android Drag and Drop

يتيح إطار السحب والإفلات في Android للمستخدمين نقل البيانات من طريقة عرض إلى أخرى طريقة العرض في التخطيط الحالي باستخدام إيماءة السحب والإفلات.  اعتبارًا من واجهة برمجة التطبيقات API 11 ، يتم دعم طريقة العرض "السحب والإفلات" إلى طرق العرض الأخرى أو مجموعات العرض. ويشمل الإطار التالي ثلاثة عناصر مهمة لدعم وظيفة السحب والإفلات -
  • Drag event class. فئة حدث السحب
  • Drag listeners. مستمعات السحب 
  • Helper methods and classes. الفئات والدوال المساعدة

عمليات السحب والإفلات The Drag/Drop Process

هناك أربع خطوات أو حالات في عملية السحب والإفلات -
  • Started − 
  • يحدث هذا الحدث عند بدء سحب عنصر في تخطيط ما ، يستدعي التطبيق الخاص بك طريقة startDrag () لإعلام النظام ببدء السحب.  توفر الوسيطات الموجودة داخل طريقة startDrag () البيانات المراد سحبها وبيانات التعريف الخاصة بهذه البيانات واستدعاء رد الظل السحب.

     يستجيب النظام أولاً عن طريق الاتصال مرة أخرى بالتطبيق للحصول على ظل السحب.  ثم يعرض ظل السحب على الجهاز.

     بعد ذلك ، يرسل النظام حدث السحب مع نوع الإجراء ACTION_DRAG_STARTED إلى مستمعي حدث السحب المسجل لجميع الكائنات عرض في التخطيط الحالي.

     لمتابعة تلقي أحداث السحب ، بما في ذلك حدث إسقاط محتمل ، يجب أن يستمع مستمع أحداث السحب إلى true ، وإذا عاد مستمع أحداث السحب إلى خطأ ، فلن يتلقى أحداث السحب للعملية الحالية حتى يرسل النظام حدث سحب مع نوع الإجراء  ACTION_DRAG_ENDED.
  • Continuing −
  • يتلقى مستمع أحداث السحب إجراء ACTION_DRAG_EXITED بعد قيام المستخدم بنقل ظل السحب خارج المربع المحيط في العرض.

      يواصل المستخدم السحب.  يرسل النظام الإجراء ACTION_DRAG_ENTERED متبوعًا بالإجراء ACTION_DRAG_LOCATION إلى مستمع أحداث السحب المسجّل للعرض حيث تدخل نقطة السحب.  قد يختار المستمع تغيير مظهر كائن العرض الخاص به استجابةً للحدث أو قد يتفاعل من خلال تمييز طريقة العرض الخاصة به.
  • Dropped −
  • يقوم المستخدم بإطلاق العنصر المسحوب داخل المربع المحيط لطريقة عرض.  يرسل النظام مستمع كائن عرض حدث السحب مع نوع الإجراء ACTION_DROP. 
  • Ended − 
  • مباشرة بعد نوع الإجراء ACTION_DROP ، يرسل النظام حدث السحب مع نوع الإجراء ACTION_DRAG_ENDED للإشارة إلى أن عملية السحب قد انتهت.

فئة حدث السحب The DragEvent Class

يمثل DragEvent حدثًا يتم إرساله من قبل النظام في أوقات مختلفة أثناء عملية السحب والإفلات.  توفر هذه الفئة بعض الثوابت والأساليب المهمة التي نستخدمها أثناء عملية السحب والإفلات.

الثوابث Constants


فيما يلي جميع الأعداد الصحيحة الأعداد الصحيحة كجزء من فئة DragEvent.
الرقم.الوصف والثابت
1
ACTION_DRAG_STARTED
إشارات بداية عملية السحب والإفلات.

2
ACTION_DRAG_ENTERED
إشارات إلى طريقة عرض أن نقطة السحب قد دخلت المربع المحيط في طريقة العرض.

3
ACTION_DRAG_LOCATION
يتم الإرسال إلى طريقة عرض بعد ACTION_DRAG_ENTERED إذا كان ظل السحب لا يزال داخل المربع المحيط بالكائن View.

4
ACTION_DRAG_EXITED
إشارات قام المستخدم بنقل ظل السحب خارج المربع المحيط في طريقة العرض.

5
ACTION_DROP
إشارات إلى طريقة عرض أن المستخدم قد أصدر ظل السحب ، وتقع نقطة السحب داخل المربع المحيط في طريقة العرض.

6
ACTION_DRAG_ENDED
إشارات إلى طريقة عرض انتهت عملية السحب والإفلات.

الدوال Methods

فيما يلي بعض الطرق المهمة والأكثر استخدامًا المتوفرة كجزء من فئة DragEvent.
الرقم.الوصف
1
int getAction()
تفقد قيمة الإجراء لهذا الحدث ..

2
ClipData getClipData()
إرجاع كائن ClipData المرسلة إلى النظام كجزء من استدعاء startDrag ().

3
ClipDescription getClipDescription()
إرجاع كائن ClipDescription الموجود في ClipData.

4
boolean getResult()
إرجاع إشارة إلى نتيجة عملية السحب والإفلات.

5
float getX()
الحصول على إحداثي X لنقطة السحب.
6
float getY()
الحصول على إحداثي Y لنقطة السحب.
7
String toString()
إرجاع تمثيل سلسلة لكائن DragEvent.

الإستماع إلى حدث السحب Listening for Drag Event

إذا كنت تريد أن تستجيب أي من طرق العرض الخاصة بك داخل Layout إلى حدث السحب ، فإن طريقة العرض الخاصة بك إما أن تقوم بتنفيذ View.OnDragListener أو إعداد طريقة رد الاتصال onDragEvent (DragEvent).  عندما يستدعي النظام الطريقة أو المستمع ، ينتقل إليهم كائن DragEvent الموضح أعلاه.  يمكن أن يكون لديك مستمع وطريقة رد اتصال لكائن العرض.  في حالة حدوث ذلك ، يقوم النظام أولاً باستدعاء المستمع ثم يتم تحديد رد الاتصال طالما أن المستمع يعود صحيحًا.
مزيج من أسلوب onDragEvent (DragEvent) و View.OnDragListener مماثل لمزيج onTouchEvent () و View.OnTouchListener المستخدم مع أحداث اللمس في الإصدارات القديمة من Android.

البدء في حدث السحل Starting a Drag Event

عليك البدء بإنشاء ClipData و ClipData.Item للبيانات التي يتم نقلها.  كجزء من كائن ClipData ، قم بتوفير بيانات التعريف المخزنة في كائن ClipDescription داخل ClipData.  لعملية السحب والإفلات التي لا تمثل حركة البيانات ، قد تحتاج إلى استخدام فارغة بدلاً من كائن حقيقي.
بعد ذلك ، يمكنك إما تمديد العرض View.DragShadowBuilder لإنشاء ظل سحب لسحب العرض أو ببساطة يمكنك استخدام View.DragShadowBuilder (View) لإنشاء ظل سحب افتراضي بنفس حجم تمرير وسيطة العرض إليه ، مع اللمس  نقطة تركزت في الظل السحب.

مثال Example

يوضح المثال التالي وظيفة السحب والإفلات البسيطة باستخدام 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");
               
               // 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;
            }
         }
      });
   }
}

فيما يلي محتوى ملف res / layout / activity_main.xml -
كود الشعار
 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">
   
   
      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" />
      
   
      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" />>
      
   
      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" />


فيما يلي محتوى res / values ​​/ strings.xml لتحديد ثوابتين جديدتين -
xml version="1.0" encoding="utf-8"?>

    name="app_name">My Application

فيما يلي المحتوى الافتراضي لـ AndroidManifest.xml -
xml version="1.0" encoding="utf-8"?>
 xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.saira_000.myapplication" >
      
   
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      
      
         android:name=".MainActivity"
         android:label="@string/app_name" >
      
         
             android:name="android.intent.action.MAIN" />
             android:name="android.intent.category.LAUNCHER" />
         

دعنا نحاول تشغيل تطبيق My Application.  أفترض أنك قمت بإنشاء إعداد بيئة تشغيل AVDwhile.  لتشغيل التطبيق من Android Studio ، افتح أحد ملفات أنشطة المشروع وانقر على أيقونة Run Eclipse Run Icon من شريط الأدوات.  يقوم تطبيق Android studio بتثبيت التطبيق على AVD الخاص بك وتشغيله ، وإذا كان كل شيء على ما يرام مع الإعداد والتطبيق ، فسيتم عرضه بعد نافذة Emulator -