سبد (0)

آموزش کشیدن و رها کردن در اندروید

کشیدن و رها کردن در اندروید (Android Drag and Drop )

قالب کشیدن و رها کردن در اندروید این امکان را برای کاربران فراهم می کند که در layout فعلی، با استفاده از حالت کشیدن و رها کردن گرافیکی، داده را از یک View به View  دیگر منتقل کنند. این قالب شامل سه مولفه اصلی زیر برای پشتیبانی از قابلیت کشیدن و رها کردن است.

کلاس رویداد کشیدن

شنودکنندگان عمل کشیدن

متدها و کلاس های کمکی

فرایند کشیدن و رها کردن

اساسا 4 مرحله یا وضعیت در فرایند کشیدن و رها کردن وجود دارد .

Started    این رویداد زمانی اتفاق می افتد که شما شروع به کشیدن یک آیتم در صفحه می کنید و اپلیکیشن شما متد startDrag()را برای اعلام آغاز عملیات drag به سیستم، فراخوانی می کند. آرگومان های موجود در متد startDrag() داده هایی که باید drag شود، فراداده­ی مربوط به این داده ها، و یک callback برای ترسیم مسیر drag  را فراخوانی می کنند.

سیستم ابتدا با فراخوانی اپلیکیشن شما برای گرفتن مسیر drag  به رویداد پاسخ می دهد، سپس مسیر drag را بر روی دستگاه نمایش می دهد.

پس از آن سیستم یک رویداد drag با نوع عمل ACTION_DRAG_STARTEDرا به شنود کننده رویداد ثبت شده برای تمام اشیا View در Layout فعلی می فرستد.

برای ادامه دریافت رویدادهای drag، از جمله یک رویداد امکان پذیرِ drop، شنود کننده باید مقدار trueرا برگرداند. اگر شنودکننده رویداد drag مقدار false را برگرداند، دیگر رویداد های drag عملیات فعلی را دریافت نمی کند، تا زمانیکه سیستم یک رویداد drag را با نوع عمل ACTION_DRAG_ENDED انتخاب کند.

Continuing   کاربر به عمل drag ادامه می دهد. سیستم عمل ACTION_DRAG_ENTERED و به دنبال آن عمل ACTION_DRAG_LOCATION را به  شنود کننده رویداد ثبت شده برای view ای که نقطه drag کردن از آن آغاز میشود، ارسال میکند. شنود کننده می تواند انتخاب کند که ظاهر اشیا view خود را در پاسخ به رویداد تغییر دهد یا می تواند با مشخص کردن view مربوطه، به رویداد واکنش نشان دهد.

شنود کننده رویداد drag یک عمل ACTION_DRAG_EXITED را بعد از اینکه کاربر  مسیر drag را از محدوده View خارج کرد، دریافت می کند.

Dropped    کاربر آیتم کشیده شده را رها می کند. سیستم به شنود کننده شی view یک رویداد drag را با نوع عمل ACTION_DROP می فرستد.

Ended    درست پس از نوع عمل ACTION_DROP، سیستم برای نشان دادن پایان عملیات drag، یک رویداد drag را با نوع عمل ACTION_DRAG_ENDED می فرستد.

کلاس DragEvent

DragEventنشان دهنده رویدادی است که به وسیله سیستم در زمان های مختلف در طول عملیات drag و drop ارسال میشود. این کلاس دارای تعدادی ثابت و متد مهم است که در طول عملیات drag و drop مورد استفاده قرار می گیرند.

ثابت ها

در بخش زیر تمام ثابت های صحیحی که به عنوان بخشی از کلاس DragEvent موجود هستند لیست شده اند.

  • ACTION_DRAG_STARTED

    سیگنال های مبنی بر  آغاز عملیات drag و drop
  • ACTION_DRAG_ENTERED

    سیگنالی به یک View مبنی بر اینکه، نقطه drag کردن وارد محدوده view شده است.
  • ACTION_DRAG_LOCATION

    بعد از عمل ACTION_DRAG_ENTERED به یک view فرستاده می شود، اگر مسیر drag کردن هنوز در محدوده اشیا view باشد.
  • ACTION_DRAG_EXITED

    سیگنالی مبنی بر اینکه کاربر مسیر drag را به خارج از محدوده View منتقل کرده است.
  • ACTION_DROP

    سیگنالی که به یک view فرستاده میشود مبنی بر اینکه کاربر مسیر drag کردن را رها کرده است و نقطه drag در محدوده View قرار دارد.
  • ACTION_DRAG_ENDED

    سیگنالی به یک View مبنی بر اینکه عملیات drag و drop به پایان رسیده اند.

متدها

در بخش زیر مهمترین و پر استفاده ترین متدهای موجود در کلاس DragEvent ارائه شده اند.

  • int getAction()

    مقدار avtion رویداد مربوطه را بررسی می کند.
  • ClipData getClipData()

    شی ClipData ارسال شده به سیستم را به عنوان بخشی از فراخوانی به startDrag() برمی گرداند.
  • ClipDescription getClipDescription()

    شی ClipDescription موجود در ClipData را برمی گرداند.
  • boolean getResult()

    نشانه ای از نتیجه عملیات drag و drop را برمی گرداند.
  • float getX()

    مختصات X نقطه drag کردن را می گیرد.
  • float getY()

    مختصات Y نقطه drag کردن را می گیرد.
  • String toString()

    نمایش رشته ای شی DragEvent را بر می گرداند.

گوش دادن به رویداد Drag

اگر شما بخواهید که هر کدام از View های شما در داخل یک Layout به رویداد drag پاسخ بدهد، آنگاه View شما متدهای callback، View.OnDragListenerیا onDragEvent(DragEvent)را پیاده سازی می کند. زمانی که سیستم متد یا شنود کننده را فراخوانی می کند، یک شی DragEvent که در بالا توصیف شد را به آنها بر می گرداند. شما می توانید هر دو مورد شنود کننده و متد callback  را برای شی View داشته باشید. در این صورت سیستم ابتدا شنود کننده را فراخوانی می کند و سپس تا زمانی که شنود کننده مقدار صحیح را برگرداند، callback تعریف شده را فراخوانی می کند.

ترکیب متد nDragEvent(DragEvent)و View.OnDragListenerشبیه به ترکیبی از onTouchEvent()و View.OnTouchListenerبه کار رفته در مورد رویدادهای لمسی در نسخه های قدیمی اندروید است.

آغاز کردن یک رویداد Drag

شما کار را با ایجاد یک ClipDataو ClipData.Itemبرای داده های منتقل شده آغاز می کنید. این آیتم به عنوان بخشی از شی ClipData، فراداده ای را عرضه می کند که در شی ClipDescriptionدرون  ClipData ذخیره میشود. برای عملیات drag و drop ای که شامل انتقال داده نیست، می توانید به جای شی واقعی از null استفاده کنید.

سپس شما می توانید یا View.DragShadowBuilderرا برای ایجاد یک مسیر drag کردن برای کشیدن View آغاز کنید و یا به سادگی از View.DragShadowBuilder(View)برای ایجاد مسیر پیش فرض drag کردن استفاده کنید که همان سایز آرگومان های View ارسالی به آن، به مرکزیت نقطه لمس کردن در مسیر drag است.

مثال

مثال زیر عملکرد یک عملیات ساده drag و drop را با استفاده از شنود کننده رویداد View.setOnLongClickListener() همراه با View.OnDragEventListener() نشان می دهد.

  • از Eclipse IDE برای ایجاد یک اپلیکیشن اندرویدی استفاده کنید و آن را تحت پکیج com.example.dragndropdemo،DragNDropDemo بنامید. در حالیکه این پروژه را ایجاد می کنید برای استفاده از سطوح بالاتر API ها،  از آخرین نسخه Target SDK و Compile With اطمینان حاصل کنید.
  • فایل src/MainActivity.java را تغییر دهید و کدهایی را برای تعریف شنودکنندگان رویداد و همچنین متدهای call back مربوط به تصویر لوگوی به کار رفته در مثال، اضافه کنید.
  • تصویر logo.png را در پوشه res/drawable-* کپی کنید. در صورتی که می خواهید تصاویر را برای دستگاه های مختلف به کار ببرید، می توانید از تصاویری با وضوح مختلف استفاده کنید.
  • فایل صفحه بندی XML res/layout/activity_main.xml را برای تعریف view پیش فرض تصویر لوگو تغییر دهید.
  • برای راه اندازی امولاتور اندروید اپلیکیشن را اجرا کنید و نتایج تغییرات اعمال شده در اپلیکیشن را بررسی کنید.

در بخش زیر محتوای تعییر یافته­ ی  src/com.example.dragndropdemo/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;
            }
         }
      });
   }
   
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return true;
   }
   
   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      // Handle action bar item clicks here. The action bar will
      // automatically handle clicks on the Home/Up button, so long
      // as you specify a parent activity in AndroidManifest.xml.
      
      int id = item.getItemId();
      
      //noinspection SimplifiableIfStatement
      if (id == R.id.action_settings) {
         return true;
      }
      return super.onOptionsItemSelected(item);
   }
}

بخش زیر محتوای فایل res/layout/activity_main.xmlاست.

 

<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>

بخش زیر محتوای فایل res/values/strings.xmlبرای تعریف دو ثابت جدید است.

 

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

بخش زیر محتوای فایل AndroidManifest.xmlاست

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.guidemo"
   android:versionCode="1"
   android:versionName="1.0" >
   
   <uses-sdk
      android:minSdkVersion="11"
      android:targetSdkVersion="22" />
      
   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      
      <activity
         android:name="com.example.guidemo.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>

اکنون می خواهیم اپلیکیشن DragNDropDemo  رااجرا کنیم. من فرض می­کنم که شما AVD خود را در زمان نصب محیط ایجاد کرده باشید. برای اجرای اپلیکیشن از Eclipse، یکی از فایل های فعالیت پروژه­ی خود را باز کنید و بر روی آیکن Run از نوار ابزار کلیک کنید. Eclipse، اپلیکیش را بر روی AVD شما نصب می کند و آن را آغاز می کند.

تمامی محصولات و خدمات این وبسایت، حسب مورد دارای مجوزهای لازم از مراجع مربوطه می‌باشند و فعالیت‌های این سایت تابع قوانین و مقررات جمهوری اسلامی ایران است.
logo-samandehi مجوز نشر دیجیتال از وزرات فرهنگ و ارشاد اسلامی پرداخت آنلاین -  بانک ملت معرفی بیاموز در شبکه سه