در این مقاله به نحوه کد نویسی رخداد دراگ و دراپ و یا کشیدن و رها کردن موس را توضیح خواهیم داد.
فریم ورک drag/drop اندروید به کاربران اجازه میدهد که داده ها را از یک نما به نمای دیگری در طرح حاضر جابجا کنند. این فریم ورک کامپوننت های زیر را برای پشتیبانی کردن از دراگ و دراپ دارا می باشد.
Drag event class.
Drag listeners.
Helper methods and classes.
پردازش دراگ و دراپ
بطور عمومی چهار گام یا مرحله در پردازش دراگ و دراپ وجود دارد.
شروع start: این رخداد زمانی روی میدهد که شما شروع به دراگ کردن یک آیتم در پنجره نرم افزار خود می کنید. نرم افزار شما متد startDrag() را فرا خوانی می کند که به سیستم شروع دراگ شدن را اعلام می کند. آرگومان های داخل متد startDrag() امکان دراگ شدن داده ها را محیا می کند، اینکار با آماده کردن metadata برای داده و فراخوانی سایه برای سایه دراگ شدن صورت میگیرد.
اولین پاسخ سیستم فراخوانی مجدد نرم افزار است برای اینکه سایه دراگ را از نرم افزار دریافت کند. و سایه را در نرم دستگاه به نمایش بگذارد.
در ادامه سیستم رخداد دراگ را همراه اکشن نوع ACTION_DRAG_STARTED ارسال خواهد کرد تا در شنونده رخداد دراگ drag event listeners ثبت شود . این عمل در تمام اشیاء در حال نمایش در نمای فعلی نرم افزار رخ خواهد داد .
برای ادامه دریافت رخداد دراگ ، که احتمالا شامل رخداد دراپ هم میشود . یک رخداد شنونده دراگ باید مقدار درست را بازگردانی کند، اگر شنونده رخداد دراگ مقدار false را بازگردانی کرد، سیستم تا زمان دریافت اکشن ACTION_DRAG_ENDED برای عملیات خود رخداد دراگ دریافت نخواهد کرد.
ادامه Continuing : کاربر به دراگ کردن ادامه میدهد ، سیستم اکشن ACTION_DRAG_ENTERED را بهمراه اکشن ACTION_DRAG_LOCATION ایجاد می کند تا شنونده دراگ را برای نقطه ای که دراگ به آن خواهد رسید ثبت کند. شنونده ممکن است که انتخاب کند که ظاهر نمایش شیئ خود را تغییر دهد تا واکنشی به رخداد نشان داده باشد . این واکنش ممکن است با روشن شدن نما رخ بدهد.
شنونده رخداد دراگ یک اکشن ACTION_DRAG_EXITED را پس از آنکه کاربر سایه دارگ را به خارج از جعبه محدوده نما برد دریافت خواهد کرد.
دراپ شده Dropped : کاربر ایتمی را که دراگ شده است را در محدوده نما رها کرده است. سیستم شنونده، نمایش شیئ را برای رخداد دراگ را با رخداد نوع ACTION_DROP را ارسال خواهد کرد.
پایان Ended : بعد از اکشن نوع ACTION_DROP سیستم رخداد drag را با نوع اکشن ACTION_DRAG_ENDED برای مشخص کردن پایان عمل رخداد دراگ ارسال خواهد کرد.
کلاس رخداد دراگ The DragEvent Class
کلاس DragEvent یک رخداد را ایجاد کرده که توسط سیستم چندین بار در هنگام عملیات دراگ و دراپ ارسال میگردد. این کلاس تعداد ثابت و متدهای مهمی که ما در طول پردازش دراگ و دراپ پردازش می کنیم را ایجاد می کند.
ثابت ها:
جدول زیر همه اعداد ثابتی که به عنوان یک بخش از کلاس DragEvent در دسترس هستند را نشان میدهد.
شماره
|
ثابت ها و توضیحات
|
1
|
ACTION_DRAG_STARTED
سیگنال های شروع عملیات دراگ و دراپ
|
2
|
ACTION_DRAG_ENTERED
سیگنال های نمایش رسیدن نقطه دراگ به محدوده قاب نمایش.
|
3
|
ACTION_DRAG_LOCATION
فرستادن به یک نما بعد از ACTION_DRAG_ENTERED در صورتی که سایه دراگ هنوز در محدوده قاب نمایش باشد.
|
4
|
ACTION_DRAG_EXITED
سیگنالهای فرستادن دراگ و سایه دراگ به خارج از محدوده قاب نما توسط کاربر
|
5
|
ACTION_DROP
سیگنال های نمایش رها کردن موس و سایه دراگ در داخل محدوده قاب نمایش توسط کاربر
|
6
|
ACTION_DRAG_ENDED
سیگنال های نمایش اینکه عملیات دراگ و دراپ به پایان رسیده است.
|
متدها
متدهای معرفی شده زیر جزء مهمترین و پرکاربردترین متدهای استفاده شده در کلاس DragEvent هستند.
شماره
|
ثابت و توضیحات
|
1
|
int getAction()
این متد یک مقدار Action را ارجاع میدهد
|
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 برای رخداد دراگ
توضیح مترجم : رخداد Listener هنگامی استفاده میشود که شما ارجاعی از نوع بله/ خیر میخواهید.
اگر میخواهید که هر یک از نماهای شما با یک طرح بندی به رخداد دراگ پاسخ بدهد و سپس نمای View.OnDragListener را بکارگیرد و یا متد فراخوانی onDragEvent(DragEvent) را ایجاد کند. هنگامیکه سیستم متد یا listener را فراخوانی کند، شیئ DragEvent توضیح داده شده در بالا به آنها ارجاع شده است. شما میتوانید متد فراخوانی و listener برای نمایش شئی را بطور همزمان داشته باشید. اگر این اتفاق رخ دهد . سیستم اول listener را فرا میخواند و سپس در صورتی که listener پاسخtrue را برگرداند، متد فراخوانی را تائید می کند.
ترکیب متد DragEvent(DragEvent) و View.OnDragListener مشابه ترکیب متد onTouchEvent() و View.OnTouchListener میباشد که برای لمس شدن در نسخه های قبلی اندروید استفاده میشد.
شروع یک Drag Event
شما با ایجاد یک ClipData کار را شروع کرده و با ClipData.Item برای انتقال داده ها کار را ادامه میدهد. ClipData.Item به عنوان یک بخش از شئی ClipData عمل میکند، برای متادیتا که در داخل شیئ ClipDescription با ClipData بکار رفته است . برای عملیات دراگ و دراپ حرکت داده را شامل نخواهد شد و شما باید مقدار NULL را بجای شیئ واقعی به آن بدهید.
در ادامه شما میتوانید View.DragShadowBuilder را توسعه داده تا سایه دراگ را برای نمایش اضافه کنید. شما میتوانید بجای اینکار بسادگی از View.DragShadowBuilder(View) استفاده کنید تا یک سایه دراگ پیشفرض اضافه کنید. این سایه پیشفرض به اندازه آرگومان های است که به آن داده شده است. این سایه با مرکزیت نطقه تماس ایجاد خواهد گردید.
مثال
مثال زیر نشان میدهد عملگر ساده دراگ و دراپ را با استفاده از View.setOnLongClickListener(),View.setOnTouchListener() و View.OnDragEventListener() را نشان میدهد.
گام
|
توضیح
|
1
|
شما از نرم افزار اندروید استودیو برای ایجاد یک نرم افزار اندریدی به نام My Application در زیر شاخه com.example.saira_000.myapplication استفاده می کنید
|
2
|
فایل src/MainActivity.java را ویرایش کنید و رخداد listeners و متد فراخوانی را برای تصویر لوگو استفاده شده در مثال اضافه کنید.
|
3
|
تصویر abc.png را در پوشه in res/drawable-* کپی کنید شما میتوانید تصویر را با رزولوشن های مختلف بکار ببرید تا برای دستگاه های مختلف عکس مناسب داشته باشید.
|
4
|
فایل XML طرحبندی layout را تغییر دهید res/layout/activity_main.xml تا نمای پیشفرض را برای عکس لوگو انتخاب کنید.
|
5
|
نرم افزار را اجرا کنید تا به شبیه ساز اندروید منتقل شوید و نتیجه تغییرات داده شده در نرم افزار را تائید کنید.
|
در زیر متن ویرایش شده اکتیویتی اصلی در فایل src/MainActivity.java. را مشاهده می کنید. این فایل میتواند دارای تمام ساختار های متدهای lifecycle باشد:
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 را مشاهده می کنید.
کد های زیر نمایانگر لوگوی 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>
کد های زیر محتوای فایل 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 را نصب کرده اید . ما روی ایکون Run در نوار ابزار کلیک کرده ایم. اندروید استودیو نرم افزار را روی شبیه ساز نصب کرده و اگر همه چیز خوب پیشرفت شما تصویر زیر را در پنجره شبیه ساز مشاهده می کنید:
روی لوگوی نرم افزار TutorialsPoint کلیک کرده و بعد از اینکه کمی از جای خود تکان خورد آن را دراگ و در مکان جدیدی دراپ کنید:
براي بهره مندي از مشاوره تخصصي در زمینه برنامه نویسی اندروید در کرج با شرکت سارگون تماس بگيريد