Event Handling ؛ کنترل رویدادها در اندروید

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

آنچه در این آموزش می‌خوانید:

  • آشنایی با فایل AndroidManifest.xml
  • آشنایی با انواع کامپوننت ها
  • معرفی رویدادها در برنامه نویسی
  • معرفی کنترل کننده ها و شنونده های رویدادها
  • نحوه کنترل رویداد عناصر موجود در اکتیویتی
  • جلوگیری از تخریب اکتیویتی هنگام چرخش صفحه نمایش و دیوایس
  • آشنایی با تگ ScrollView برای اضافه کردن قابلیت اسکرول به اکتیویتی

 

این جلسه در قالب PDF و در ۴۰ صفحه تهیه شده که در ادامه چند صفحه‌ ابتدایی را مشاهده می‌کنید:

به نام خدا. قبل از شروع مبحث کنترل رویدادها به معرفی یکی از مهم ترین بخش های اپلیکیشن اندرویدی می پردازیم :
فایل AndroidManifest.xml :
به طور کلی، اطلاعات اصلی و مهم اپلیکیشن درون این فایل نگهداری می شود. یک پروژه جدید با نام Events و API9 ساختیم. از مسیر manifests فایل AndroidManifest.xml را باز می کنیم :

AndroidManifest.xml

در خط ۳ نام پکیج قرار گرفته است.خطوط ۷ و ۸ به ترتیب مربوط به آیکون و نام اپ ما می باشد که در لیست اپلیکیشن های نصب شده روی دیوایس نمایش داده می شود. در خط ۱۱ مشاهده می کنید اکتیویتی MainActivity تعریف شده. به همین صورت هر اکتیویتی که بخواهیم به پروژه اضافه کنیم باید درون مانیفست نیز اضافه شود. اطلاعات دیگر مانند تِم (قالب) اپلیکیشن، مجوزها، کامپوننت ها و … همگی درون این فایل تعریف می شوند.
Theme (تم) مربوط به ظاهر برنامه می شود که در مباحث آینده به آن می پردازیم.
از مجوزها می توانیم به مجوز دسترسی اپلیکیشن به دوربین، مخاطبین (دفترچه تلفن)، میکروفون، ارسال SMS، و … اشاره کرد. حتما هنگام نصب یک اپلیکیشن روی گوشی اندرویدی خود، با لیستی شامل Permission های مختلف مواجه شده اید که سیستم عامل از شما می خواهد با آگاهی از دسترسی هایی که این اپ می تواند روی تلفن هوشمند شما داشته باشد اقدام به نصب نمائید. برای مثال شما قصد ساخت اپلیکیشنی دارید که کاربر توسط دوربین تلفن یا تبلت خود عکس بگیرد و به ویرایش آن بپردازد. برای اینکه اپ شما به دوربین دیوایس کاربر دسترسی داشته باشد باید مجوز آن را درون مانیفست اضافه کنید.
کامپوننت ها هم شامل Activity ها، Service ها، Broadcast Receiver ها (دریافت کننده اطلاعات) و Content Provider ها (تامین کننده محتوا) هستند.
با اکتیویتی قبلا آشنا شدیم. Service ها مربوط به پردازش های اپلیکیشن هستند.
Broadcast Receiver پل ارتباطی بین اپلیکیشن و سیستم عامل و سایر اپلیکیشن هاست.
Content Provider هم مربوط به مدیریت داده ها می باشد.
هدف از معرفی کامپوننت ها آشنایی مختصر با این موارد بود. در ادامه آموزشها مفصل به معرفی آنها می پردازیم.
توضیحات بالا اهمیت فایل مانیفست را می رساند و روشن است که سیستم عامل اندروید اطلاعات مورد نیاز خود درباره اپلیکیشن را از این فایل می گیرد.

رویداد یا Event چیست

همانطور که در پاراگراف قبل عنوان شد، اکتیویتی ها یکی از کامپوننت های سیستم عامل اندروید هستند. رویدادها روشی است جهت جمع آوری اطلاعات درباره نحوه تعامل کاربر با کامپوننت های اپلیکیشن. اندروید رویدادها را به صورت صف FIFO (First in First out به این معنی که هر رویدادی که زودتر اتفاق بیفتد زودتر پردازش می شود) نگهداری و پردازش می کند.
در مدیریت رویدادها با سه مفهوم اساسی سروکار داریم :
Event Listeners ، Event Listener Registeration و در نهایت Event Handlers.
واژه Listener به معنی شنونده بوده بنابراین Event Listeners را می توان شنونده رویدادها ترجمه کرد.به طور خلاصه کاربر وقتی روی یک view (به عنوان مثال یک دکمه) کلیک می کند، این رویداد توسط سیستم عامل شنود می شود.توسط Event Listener Registeration رویداد ثبت و توسط Event Handlers کنترل می شود. در صفحه
https://developer.android.com/guide/topics/ui/ui-events.html
انواع رویدادهای اندروید لیست شده که به معرفی آنها می پردازیم :

کنترل کننده رویداد شنونده رویداد
onClick() View.OnClickListener()

متد زمانی اجرا می شود که کاربر یکی از ویجت های موجود در صفحه نمایش مانند دکمه، تصویر، متن و … را لمس کند

onLongClick() View.OnLongClickListener()

متد مشابه متد قبل بوده با این تفاوت که عمل لمس کردن ویجت مدنظر باید یک ثانیه و یا بیشتر طول بکشد.

onFocusChange() View.OnFocusChangeListener()

متد زمانی اجرا می شود که عمل فوکوس (تمرکز) از روی ویجت موردنظر برداشته شود. یعنی ویجتی که توسط کاربر لمس شده، رها شود.

onKey() View.OnKeyListener()

متد زمانی اجرا می شود که روی ویجت عمل فوکوس انجام شده و یا یک کلید سخت افزاری فشرده شود.

onTouch() View.OnTouchListener()

متد زمانی اجرا می شود که کاربر هر عملی را بر روی صفحه نمایش انجام دهد مانند لمس دکمه یا رها کردن آن، لمس قسمتی از صفحه و …

onCreateContextMenu() View.OnCreateContextMenuListener()

این متد زمانی اجرا می شود که یک منو ساخته شده.

خب! حالا وقت آن رسیده که مفاهیم را در قالب پروژه ای با عنوان شمارنده بررسی کنیم.

ابتدا یک پروژه جدید با نام دلخواه می سازیم. ما نام Counter را برای پروژه خودمان انتخاب کردیم :

ساخت پروژه اندروید

تعیین Minimum SDK

پس از انتشار نسخه ۲٫۲ اندروید استودیو، حداقل API یی که در لیست Minimum SDK قرار داده شده API 9 می باشد و به این معنی است که تقریبا صددرصد دیوایس های اندرویدی از API 9 به بالا هستند و نیازی به ساخت اپلیکیشن برای نسخه های پایین تر نیست. ما هم به تصمیم گوگل احترام گذاشته، API 9 را انتخاب می کنیم. همچنین از چند نسخه اخیر، گزینه Empty Activity جایگزین Blank Activity شده که همین را انتخاب می کنیم.

Empty Activity

مشخصات اکتیویتی

گزینه Backwards Compatibility (AppCompat) مربوط به استفاده از کتابخانه AppCompat داخل پروژه می باشد که در فصل قبل آشنا شدیم. در نسخه ۲٫۲ امکانات جدیدی به اندروید استودیو اضافه شده که یکی از آنها Layout Inspector حرفه ای می باشد که در تصویر زیر مشاهده می کنید :

اضافه شدن Layout Inspector

البته با استفاده از گزینه های بالا – سمت چپ می توان قسمت BluePrint را فعال یا غیرفعال کرد. متن Hello World پیش فرض را حذف و با کلیک روی صفحه پیش نمایش، قسمت Properties مربوط به اکتیویتی ظاهر شده که یک بک گراند به دلخواه انتخاب یا کد رنگ Hexadecimal آن را وارد می کنیم.

تغییر بک گراند اکتیویتی

همچنین اکتیویتی را از RelativeLayout به LinearLayout تغییر دادیم تا اجزایی که به اکتیویتی اضافه می کنیم زیر یکدیگر قرار بگیرند (اضافه کردن خاصیت orientation یادتان نرود). در ابتدا پروژه ما شامل دو TextView و دو Button می باشد که از دکمه ها برای اضافه و کم کردن عدد و TextView برای نمایش عبارت “شماره” و خروجی int استفاده می شود.

اضافه کردن view ها به اکتیویتی

در اینجا نیازی به نوشتن دستی کد xml ویجت ها ندیدیم و به راحتی از پالت سمت چپ، ویجت ها را کشیده و روی صفحه پیش نمایش قرار دادیم. TextView1 را به “شماره” تغییر می دهیم.TextView دوم بناست برای نمایش عدد خروجی (int) استفاده شود که در ابتدا باید عدد صفر را نمایش دهیم.
کد activity_main.xml به این صورت شد :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    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="ir.android_studio.counter.MainActivity"
    android:background="@color/colorPrimary">

    <TextView
        android:text="@string/top_txt"
        android:textSize="30sp"
        android:textAlignment="center"
        android:textColor="@color/t_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

    <TextView
        android:text="@string/result"
        android:textSize="70sp"
        android:textAlignment="center"
        android:textColor="@color/t_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/resultText" />

    <Button
        android:text="@string/plus"
        android:textSize="25sp"
        android:background="@color/button_bg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_plus" />

    <Button
        android:text="@string/minus"
        android:textSize="25sp"
        android:background="@color/button_bg"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_minus" />

</LinearLayout>

کد فایل رنگها (colors.xml) :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#dedede</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="t_top">#665454</color>
    <color name="t_result">#de0707</color>
    <color name="button_bg">#7bc11a</color>
</resources>

توضیح : این فایل مشابه strings.xml بوده به اینصورت که با تعریف رنگها داخل این فایل، در کل پروژه می توانیم به رنگها دسترسی داشته که به بهینه شدن اپ ما کمک می کند.
کد فایل dimens.xml :

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>

اندروید استودیو به صورت پیش فرض از این فایل برای تعریف فاصله اکتیویتی از ۴ جهت صفحه نمایش استفاده کرده. مزیت استفاده از این فایل به جای تعریف مستقیم واحدها درون کد اصلی، مشابه String ها و رنگ ها می باشد. استفاده مستقیم رشته ها، رنگ ها و واحدهای اندازه گیری درون کد اصلی با عنوان Hardcode شناخته می شود، به معنی کدِ سخت. که اندروید استودیو نیز از شما ایراد گرفته و پیشنهاد می کند استفاده از Hardcode را به کمترین میزان و در بهترین حالت به صفر برسانید تا هم برنامه بهینه تری داشته باشید هم اینکه هرگاه نیاز به ایجاد یک تغییر جزئی در یک یا چند قسمت از پروژه را داشتید، به سرعت بتوانید تغییر دلخواه را انجام دهید. به عنوان مثال در این پروژه ما یک بار رنگ پس زمینه دکمه ها را درون colors.xml تعریف و ۳ بار استفاده کرده ایم. هرگاه بخواهیم پس زمینه دکمه ها را تغییر بدهیم کافیست برای یک بار کد رنگ را جایگزین کد فعلی کنیم. اما در حالت معمول که کد رنگ را درون هر دکمه جداگانه تعریف کرده ایم نیاز به ۳ مرتبه جایگزینی خواهد بود.
توجه : به دلیل اینکه توضیحات کامل در خصوص dimens.xml شامل این فصل آموزشی نمی شود، فعلا واحدها را به صورت هاردکُد استفاده می کنیم.
کد فایل رشته ها (strings.xml) :

<resources>
    <string name="app_name">شمارشگر</string>
    <string name="top_txt">شماره</string>
    <string name="result">0</string>
    <string name="plus">اضافه کن</string>
    <string name="minus">کم کن</string>
</resources>

خروجی :

اجرای پروژه روی شبیه ساز جنی موشین

حالا به سراغ فایل جاوای اکتیویتی یعنی MainActivity.java می رویم. محتوای اولیه این فایل به اینصورت می باشد :

package ir.android_studio.counter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

با توجه به اینکه خروجی کد ما اعداد صحیح هستند، از متغیر int استفاده می کنیم. متغیری از جنس int میسازیم تا مقادیر اعداد صحیح را درون خود ذخیره نماید. داخل کلاس اصلی اکتیویتی متغیر را تعریف می کنیم با یک نام دلخواه :

package ir.android_studio.counter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    int counter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

حالا مقدار پیش فرض یعنی صفر را برای این متغیر درون متد onCreate تعریف می کنیم. ویجتی که با آی دی resultText ساخته بودیم از نوع TextView بود که قرار است وظیفه نمایش عدد را بر عهده بگیرد. پس با استفاده از id بین کد جاوا و بخش ویجت های صفحه ارتباط برقرار می کنیم و تعیین می کنیم عدد خروجی جایگزین عدد پیش فرض یعنی صفر شود :

package ir.android_studio.counter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    int counter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        counter = 0;
        TextView Number = (TextView)findViewById(R.id.resultText);
    }
}

مشاهده می کنید counter را برابر عدد صفر قرار دادیم.
خط بعد را بررسی می کنیم : با توجه به اینکه برای نمایش عدد از ویجت TextView استفاده کرده ایم، همین کلاس را نوشته و یک نام دلخواه انتخاب می کنیم که ما Number در نظر گرفتیم. یک مساوی از نوع انتساب قرار داده و سپس برای اینکه به سیستم عامل اعلام کنیم از چه نوع View ای استفاده کرده ایم، نوع آن را مجدد داخل پرانتز می نویسیم (این عمل Casting نام دارد که در آموزشهای جاوا توضیح داده شده). در نهایت و بدون ایجاد فضای خالی، متد findViewById(R.id.resultText) را اضافه می کنیم که مشخص است کار آن ایجاد دسترسی به View ای با آی دی resultText می باشد. R.id دسترسی به Resource ها از طریق id را فراهم می کند. از این به بعد هر خروجی از نوع String که داخل شئ Number بریزیم در این TextView نمایش داده خواهد شد. نوبت به تعریف عملکرد Button ها می رسد. به صورت زیر، از دو دکمه که برای کم و زیاد کردن عدد نمایشگر ساخته ایم دو شئ می سازیم و توسط id آنها به شئ مربوطه هرکدام متصل می کنیم :

package ir.android_studio.counter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    int counter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        counter = 0;
        TextView Number = (TextView)findViewById(R.id.resultText);
        Button btn_1 = (Button)findViewById(R.id.button_plus);
        Button btn_2 = (Button)findViewById(R.id.button_minus);
    }
}

همانطور که در آموزش “اکتیویتی” توضیح دادیم، هر یک از این کلاس هایی که استفاده می کنیم قبلا درون سیستم عامل اندروید تعریف شده اند و برای دسترسی به آنها ملزم به import کردن کلاسها به ابتدای کد هستیم. هنگامی که کلاس TextView را می نویسید، اگر لیست باز شد و TextView را از لیست انتخاب کردید، عمل import نیز به صورت خودکار انجام می شود. اما اگر از لیست انتخاب نکردید و کلاس را خودتان تا انتها نوشتید یا به هر علتی کلاس در بالای کد جاوا خودکار import نشد، کافیست روی نام کلاس کلیک کنید تا پیغام مشابه زیر نمایش داده شود که به ما اعلام می کند عمل import را می توانیم با دو کلید alt + enter انجام دهیم :

ایمپورت خودکار کلاس رویدادها

ایمپورت خودکار کلاس رویدادها

جهت مطالعه ادامه آموزش، فایل PDF را دانلود نمائید

توجه : سورس پروژه داخل پوشه Exercises قرار داده شده است.

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

دانلود نسخه کامل این آموزش به همراه سورس پروژه
تعداد صفحات : ۴۰
حجم : ۳ مگابایت
قیمت : ۲۲ هزار تومان
توجه: صرفا در صورتی از درگاه پشتیبان استفاده کنید که قادر به پرداخت از طریق سبد دانلود نباشید.
افزودن به سبد دانلود درگاه پشتیبان
این مطلب چقدر برایتان مفید بود؟ لطفا امتیاز دهید
4.1/5 - (7 امتیاز)
پرسش‌ها و دیدگاه‌های کاربران
دوره آموزش برنامه نویسی اندروید
دوره آموزش برنامه نویسی اندروید

با دریافت این دوره به تمامی آموزش‌های غیر رایگان و رایگان موجود در وب سایت دسترسی دارید که تخفیفی برای آموزش‌های غیر رایگان نیز درنظر گرفته شده. این پکیج به دو صورت دانلودی و ارسال پستی ارائه می‌گردد.
آموزش‌های اندروید استودیو در دو دسته «پایه» و «تکمیلی» منتشر می‌شوند.
آموزش‌های پایه شامل مباحث اصلی و ضروری و آموزش‌های تکمیلی مطالبی است که می‌بایست در کنار مطالب اصلی بررسی شود.
با خرید این دوره، به تمامی آموزش‌های غیر رایگانی که در آینده منتشر می‌شود نیز به صورت رایگان دسترسی خواهید داشت!

یک دیدگاه بنویسید

پرسش‌های زیر تایید و پاسخ داده نـــخواهند شد:
۱: جزء موارد مطرح شده در صفحات مشکلات و پرسش‌های رایج و بروزرسانی‌های محتوای آموزشی باشد
۲: سوال قبلا توسط کاربران در دیدگاه‌ها مطرح و پاسخ داده شده باشد
۳: پرسش خارج از مبحث آموزشی موجود در این صفحه باشد