Event Handling (مدیریت رویداد) در اندروید

رویدادها یک راه مفید برای جمع آوری داده ها در مورد تعامل کاربر با اجزای تعاملی برنامه ها است. مانند دکمه های فشار و یا صفحه نمایش لمسی و غیره. فریم ورک اندروید یک صف رویداد را مانند first-in, first-out (FIFO) در خود نگه میدارد. شما میتوانید این رویداد ها را در نرم افزار خود دریافت و براساس آنها عکس العمل مناسبی ایجاد کنید.

در زیر لیستی از موضوعات مرتبط با مدیریت رخدادهای اندروید ذکر شده است.

Event Listeners:یک Event Listeners یک رابط در کلاس view است، که دارای یک متد فراخوانی میباشد. این متدها با فریم ورک اندروید زمانی فراخوانی میشوند ، که رخداد به وقوع بپیوندد . تا شنونده رخداد ایجاد شود و ارتباط بین کاربر با عملکرد کاربر را در ظاهر نرم افزار حفظ کند. یعنی وقتی کاربر کاری انجام میدهد نرم افزار واکنش نشان دهد.

Event Listeners Registration:پردازشی است که توسط یک Event Handler که خود توسط یک  Event Listener ایجاد شده انجام میشود . بنابراین آن  handler هنگامیکه Event Listener رخدادی را آغاز می کند، فراخوانی میشود. یعنی هنگامیکه کاربر کاری انجام میدهد یک پردازشگر ثبت رخداد، شنونده آن رخداد را ثبت و میتواند نسبت به آن عکس العمل نشان دهد.

Event Handlers:وقتی که یک رویداد رخ میدهد و ما یک event listener برای رخداد ثبت می کنیم ، event listener فراخوانی Event Handlers را به عهده می گیرد. اینکار متدی برای مدیریت یک رخداد است.

Event Listeners & Event Handlers

Event Handlers

مدیریت کنندگان رویداد

Event Listeners

شنوندگان رویداد و توضیحات

onClick() OnClickListener()

این متد زمانی که کاربران روی المانی کلیک و یا المانی را میفشارند و یا حتی روی یک المان مانند دکمه ،متن، عکس و غیره فوکوس می کنند فراخوانی میشود .شما از متد onClick() برای مدیریت کردن رخداد های مانند این استفاده می کنید.

onLongClick() OnLongClickListener()

این متد زمانی فراخوانی میشود که کاربر  روی آیتمی کلیک و یا آیتمی برای مدت یک یا چند ثانیه را لمس می کند و یا روی ایتمی مانند دکمه، متن، عکس و غیره فکوس می کند. شما از متد onLongClick() برای مدیریت این رخداد ها استفاده میکنید.

onFocusChange() OnFocusChangeListener()

این متد زمانی فراخوانی میشود که یکی از عناصر فکوس خود را از دست میدهد. کاربر از روی آن عنصر به سایر قسمت های صفحه میرود شما از رخداد onFocusChange() برای چنین رخداد های استفاده می کنید

onKey() OnFocusChangeListener()

این متد زمانی فراخوانی میشود که کاربر روی آیتمی فکوس کرده و دکمه ای را فشرده و یا رها میکند .

شما از متد onKey() برای مدیریت کردن چنین رخداد های استفاده می کنید.

onTouch() OnTouchListener()

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

شما از رخداد onTouch() برای چنین رخداد های استفاده خواهید کرد.

onMenuItemClick() OnMenuItemClickListener()

ین متد وقتی فراخوانی میشود که کاربران یکی از آیتم های منو را انتخاب می کنند .

شما از متد onMenuItemClick() برای مدیریت چنین رخداد های استفاده می کنید.

onCreateContextMenu() onCreateContextMenuItemListener()

این متد هنگامی فراخوانی میشود که منوی راست کلیک ایجاد میشود این منو در دستگاه ها با کلیک طولانی ایجاد خواهد شد.

کلاس view شنونده های خیلی بیشتری نسبت به آنچه در جدول بالا آورده شده است را ارائه می دهد. بنابراین چنان چه قصد ساختن یک اپلیکیشن پیچده را دارید، توصیه می کنم برای دیدن لیست کامل شنونده های رویدادها (Event Listener) به سایت رسمی اندروید مراجعه کنید.

 ایجاد  Event Listeners

ثبت یک رخداد زمانی انجام میشود که یک Event Handler با یک Event Listener ایجاد شود. به این ترتیب یک متد مدیریت رخداد ایجاد میشود و این اتفاق زمانی رخ میدهد، که یک Event Listener رخداد را به انجام رسانده باشد. چندین روش برای اینکار وجود دارد. ما در اینجا به سه راه اصلی که برای موقعیت های پایه به کار میروند می پردازیم.

  • استفاده از یک کلاس Anonymous Inner
  • پیاده سازی کلاس Activity روی رخداد موجود.
  • استفاده از فایل طرح بندی activity_main.xml برای تعریف پوشه مدیریت رخداد

در قسمت ها زیر مثال های برای درک بهتر این مفاهیم ایجاد شده است.

Touch Mode (حالت لمسی)

کاربران با کمک کلید ها و دکمه ها و یا لمس صفحه میتوانند با نرم دستگاه خود ارتباط برقرار کنند.لمس صفحه دستگاه را به حالت touch mode وصل می کند. کاربران میتوانند با سخت افزار با فشردن تصویر دکمه و سایر کنترل ها ارتباط برقرار کنند. برای چک کردن اینکه دستگاه در حالت Touch Mode است میتوانید از متد InTouchMode() در کلاس View استفاده کنید.

فکوس Focus

یک نما یا یک ابزار در حالت فکوس روشن شده و یا چشمک میزند ، این به این معنی است که این ابزار آماده دریافت دستور کاربر است.

isFocusable(): این متغییر مقدار درست و یا غلط را باز میگرداند.

isFocusableInTouchMode(): این حالت کنترل می کند که آیا کنترلر در حالت لمسی هم قبل فکوس است یا خیر گاهی اوقالت ابزار تنها در صورت فعال بودن صفحه کلید قابل فکوس شدن است.

android:foucsUp="@=id/button_l"

onTouchEvent()

public boolean onTouchEvent(motionEvent event){
   switch(event.getAction()){
      case TOUCH_DOWN:
      Toast.makeText(this,"you have clicked down Touch button",Toast.LENTH_LONG).show();
      break();
   
      case TOUCH_UP:
      Toast.makeText(this,"you have clicked up touch button",Toast.LENTH_LONG).show();
      break;
   
      case TOUCH_MOVE:
      Toast.makeText(this,"you have clicked move touch button"Toast.LENTH_LONG).show();
      break;
   }
   ret

مثال های Event Handling

Event Listeners Registration با استفاده از توابع داخلی کلاس:

در این روش از متد های کلاس listener برای پیاده سازی شنونده (listener) استفاده می شود. استفاده از این روش زمانی مفید است که هر کلاس فقط به یک کنترل مخصوص اعمال شده باشد و همچنین در این حالت می توانیم آرگومان هایی را به event handler ارسال کنیم. زیرا در این روش می توانیم بدون فراخوانی کردن ارجاع دهنده های اکتیویتی، به متغییر های اختصاصی (private) تعریف شده در اکتیویتی دسترسی داشته باشیم.

اما اگر بخواهیم یک handler را به بیش از یک control اعمال کنیم ، باید مجموعه ای از کدهای تکراری را برای هر گرداننده بنویسیم و چنانچه حجم کدها زیاد باشد، حفظ و رسیدگی به آن ها تبدیل به یک کار دشوار خواهد شد.

این مثال در چند مرحله ی ساده نشان می دهد که چگونه یک handler را برای رویداد کلیک (click event) ، با استفاده از توابع داخلی ثبت کنیم.

مرحله توضیحات
1 با استفاده از Android Studio IDE یک برنامه اندروید ایجاد کنید و به عنوانMy Application تحت بسته com.example.myapplication نامگذاری کنید. نحوه ی ایجاد پروژه ی جدید در بخش آموزشی مثال !Hello World توضیح داده شده است.
2 فایل src/MainActivity.java را برای افزودن دو دکمه listeners و handleers تغییر دهید.
3 محتوای پیش فرض res/layout/activity_main.xml را تغییر دهید تا کنترل های رابط کاربری را شامل شود.
4 نیاز به تعریف ثابت های رشته پیش فرض نیست.
5 اپلیکیشن را با شبیه ساز اندروید اجرا کنید و نتیجه را مورد بررسی قرار دهید.

در زیر محتوای تغییر یافته ی فایل src/com.example.My Application/MainActivity.java قرار دارد:

package com.example.myapplication;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
   private ProgressDialog progress;
   Button b1,b2;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      progress = new ProgressDialog(this);

      b1=(Button)findViewById(R.id.button);
      b2=(Button)findViewById(R.id.button2);
      b1.setOnClickListener(new View.OnClickListener() {
         
         @Override
         public void onClick(View v) {
            TextView txtView = (TextView) findViewById(R.id.textView);
            txtView.setTextSize(25);
         }
      });

      b2.setOnClickListener(new View.OnClickListener() {
         
         @Override
         public void onClick(View v) {
            TextView txtView = (TextView) findViewById(R.id.textView);
            txtView.setTextSize(55);
         }
      });
   }
}

محتوای res/layout/activity_main.xml file :

<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context=".MainActivity">
   
   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Event Handling "
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp"/>
      
   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point "
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_above="@+id/imageButton"
      android:layout_centerHorizontal="true"
      android:layout_marginBottom="40dp" />
      
   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_centerVertical="true"
      android:layout_centerHorizontal="true" />
      
   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Small font"
      android:id="@+id/button"
      android:layout_below="@+id/imageButton"
      android:layout_centerHorizontal="true" />
      
   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Large Font"
      android:id="@+id/button2"
      android:layout_below="@+id/button"
      android:layout_alignRight="@+id/button"
      android:layout_alignEnd="@+id/button" />
      
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello World!"
      android:id="@+id/textView"
      android:layout_below="@+id/button2"
      android:layout_centerHorizontal="true"
      android:textSize="25dp" />
      
</RelativeLayout>

در زیر ، محتویات res/values/stringings.xml برای تعریف دو ثابت جدید آورده شده است:

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

در زیر ، محتویات پیش فرض AndroidManifest.xml آورده شده است:

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

اکنون برنامه My Application را اجرا کنید. فرض میکنم AVD را در حین انجام تنظیمات محیط ایجاد کرده اید.
برای اجرای برنامه از Android Studio، یکی از فایل های اکتیویتی پروژه خود را باز کنید و روی آیکون اجرا  در نوار ابزار کلیک کنید. Android Studio ، این برنامه را در AVD خود نصب می کند و آن را اجرا می کند و اگر همه چیز تنظیم باشد و برنامه شما مشکلی نداشته باشد، پنجره Emulator با دو گزینه ی large font و small font را خواهید دید.

سی شارپ

حال اگر روی دکمه ها کلیک کنید می بینید که اندازه  فونت Hello World  تغییر می کند. علت این تغییر این است که هنگام رخ دادن هر رویداد کلیک، تابعی که برای کنترل رویداد کلیک شدن هر دکمه ثبت شده است فراخوانی می گردد.

تمرین

پیشنهاد می کنم که event handler های مختلفی برای رخداد های مختلف ایجاد کرده تا مطمئن شوید که این مبحث را بدرستی درک کرده اید. رویدادهای مربوط به منو، spinner، ویدجت جمع کننده ها کمی متفاوت هستند، اما آنها نیز بر اساس مفاهیم توضیح داده شده در بالا هستند.