خانه / آموزش / آموزش زبان برنامه نویسی اندروید – قسمت چهارم

آموزش زبان برنامه نویسی اندروید – قسمت چهارم

دیگر برنامه اندروید برای موبایلتان را خودتان بنویسید.
زبان اندروید
قسمت سوم:
وقتی دارید برنامه تان را می‌سازید احتمال زیاد از منابع بیرونی هم استفاده خواهید کرد، مثل فایلهای ویدیویی یا شنیداری، تصاویر، xml و … پس باید بدونید چطور از داخل برنامتون به این منابع ارجاع بدید. منابع برنامتون داخل پوشه ی res ذخیره می شن. و یه سری فایلها به صورت خودکار بهش اضافه می شه مثل :
layout : شامل فایل های xml ای که مربوط به محیط های کاربریه.
values : شامل تمام مقادیریه که توی برنامتون تعریف می کنید و بهشون یه اسم می دید و بعدا با اون اسم بهشون رجوع می کنید و ازشون استفاده می کنید.
فایل string.xml هم به طور پیش فرض در این فولدر به وجود اومده. نحوه‌ی کارکرد string.xml این طوریه که ما یه سری منابع رشته‌ای داریم که مثلا ‌(با توجه به تصویر) هرجا که تو برناممون بخوایم از Hello World, Main! استفاده کنیم، به جاش می تونیم به این منبع ارجاعش بدیم و بنویسیم hello.

حالا چرا این منابع رو بیرون نگه می‌داریم؟ به خاطر اینکه بتونیم متغیرهای سراسری (global) داشته باشیم، مثلا می تونیم چند تا فولدر برای زبان های مختلف داشته باشیم و فقط لازمه که به فایل xml مربوط به اون زبان بریم و دیگه لازم نیست تمام کدهای برناممون رو به خاطر تغییر زبان کاربر تغییر بدیم.
۲.اگه به سایت اصلی توسعه اندروید مراجعه کنید یه قسمت داره به اسم API Guide که توش راهنمایی های مفیدی برای ساخت برنامه کرده، یکی از این راهنماها مربوط به منابع می شه، خود اندروید به طور پیش فرض یه سری از فولدرها رو تو res تشخیص می‌ده مثلا
اگه فولدر anim رو درست کنید و توش یه فایل xml مخصوص انیمیشن بذارید، اندروید متوجه می شه که انیمیشنه. (تو آموزش های بعدی مفصل به انیمیشن می پردازیم).
یا مثلا اگه می‌خواید یه لیستی از رنگ ها رو در برنامتون استفاده کنید می تونید تو فولدر color بذاریدشون.
هر کدوم از عکس‌هامون یا هر فایل xml مربوط به گرافیک در داحل فولدر drawable قرار می گیره.
فولدر layout شامل فایلهای xml مربوط به چیدمان صفحه است.
اگه بخوایم منو برای برناممون بسازیم (که بعدا آموزش داده خواهد شد) باید اونو تو فولدر menu بذاریم و …
چون تمام این منابع نوعی assets هستن، ممکنه از خودتون بپرسید پس این فولدر assets چیه (معمولا بالای فولدره bin هست)، در واقع می تونید منابعتون رو تو این فولدر بذارید ولی نمی تونید با یک id بهشون ارجاع بدید. به همین خاطر بهتره تمام منابع رو توی همون فولدر res قرار بدیم چون به طور خودکار براشون id ساخته می شه و با دستور R.id می تونید بهشون رجوع کنید.

۳.اگه تو زیر شاخه های فولدر res دقت کرده باشید، خود فولدر drawable به تنهایی وجود نداره بلکه سه تا فولدر drawable-hdpi، drawable-ldpi و drawable-mdpi وجود دارن، این به خاطر یک ویژگی مهمه اندرویده که دستگاه ها رو به سه وضوح تصویر تقسیم بندی کرده : دستگاه‌های با وضوح تصویر بالا (High dpi)، دستگاه‌های با وضوح تصویر متوسط (Medium dpi) و دستگاه‌های با وضوح تصویر پایین (Low dpi). برای هر کدوم از این وضوح تصویرهای مختلف می‌تونیم assetهای مربوط به خودشون رو بذاریم، و سیستم اندروید با توجه به دستگاهی که داره روش اجرا می‌شه، asset مربوطه رو بیرون می‌کشه و در برنامه ازش استفاده می کنه (توی یه آموزش دیگه بهش می‌پردازیم) ولی فقط بدونید که اگر از یه asset خواستید که تو همه‌ی وضوح تصاویر استفاده بشه، کافیه فقط توی drawable-hdpi بذاریدش، اون وقت تو یه دستگاه با وضوح تصویر متوسط یا پایین هم سیستم از تو فولدر drawable-hdpi برشون می‌داره.
۴.راحت‌ترین راه برای اضافه کردن asset به برنامه‌تون اینه که محتوایی که می خواید رو بکشید و تو فولدر مورد نظر ول کنید.
برای این که به پیغام خطا برخورد نکنید حواستون باشه اسم asset هایی که می‌خواید وارد کنید فقط می‌تونه شامل حروف a تا z، اعداد ۰ تا ۹ و خط زیر باشه.

۵.تو فولدر gen اگه R.java رو باز کنید، می‌بینید که به اون asset جدیدی که اضافه کردید یه عدد نسبت داده، لازم نیست برای ارجاع به این asset اون عدد رو استفاده کنید بلکه از راه دیگه ای این کارو می‌کنیم که الان توضیح می‌دم. (حواستون باشه که اصلا تغییری هم توی فایل R.java ایجاد نکنید چون این فایل به طور خودکار درست می‌شه و اگه تغییرش بدید برنامتون به هم می‌ریزه.)

۶.من برای این آموزش یه پروژه‌ی جدید ساختم و تا اینجا فقط یه عکس به فولدر drawable-hdpi اضافه کردم، از فولدر res به layout برید و فایل xml اصلی تون رو انتخاب کنید (برای من main.xml هست)، اون فیلد متنی رو پاک کنید، به جاش می‌خوایم عکسی که به پروژه اضافه کردیم رو بذاریم، از منوی کنار Images & Media رو انتخاب کنید و اون المانی که تو عکس دورش قرمز شده رو انتخاب کنید و به داخل صفحه بکشید و ول کنید، حالا ازتون می‌خواد منبع عکس رو مشخص کنید.

برای اینکه متوجه بشید دقیقا چه اتفاقی افتاده، به قسمت ویرایش متنی xml برید، تو مشخصات این تصویر یه قسمت داره به اسم android:src که با کد @drawable/androidcode_logo به تصویر مورد نظر ارجاع داده.

اصولا برای ارجاع به هر چیزی از علامت @ استفاده می‌کنیم.مثلا اینجا بعد از علامت @ می خوایم به drawable بریم.

و بعد هم یه تصویر دیگه رو انتخاب می‌کنیم، مثل ic_launcher.

دقت کنید که برای رسیدن به androidcode_logo یا هر asset دیگه‌ای، نیازی نبود که بنویسیم @drawable-hdpi فقط کافی بود از @drawable استفاده کنیم. اینکه این asset از کدوم وضوح تصویر انتخاب بشه رو، خود سیستم عامل اندروید با توجه گوشی کاربر انجام می‌ده. حالا اگه به قسمت گرافیکی main.xml بریم، مشاهده می شود که تصویر عوض می گردد.

خوب این روش ارجاع در فایل های xml بود، حالا اگه از فایل‌های جاوا بخوایم به منابعمون ارجاع بدیم باید چی کار کنیم؟
۷.اول یه ارجاع از خود ImageView می‌گیریم :
ImageView ax = (ImageView) findViewById (R.id.imageView1);
بعد منبع این ImageView رو می‌ذاریم عکسی که می‌خوایم :
ax.setImageResource(R.drawable.androidcode_logo);

این دستور باعث می‌شه وقتی که برنامه اجرا شد، منبع عکس از اون چیزی که بوده، تغییر پیدا کنه به R.drawable.androidcode_logo و وقتی برنامه رو اجرا می‌کنیم، این خروجی رو می‌بینیم.

فایل main.xml :

http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical” >
android:id=”@+id/imageView1″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:src=”@drawable/ic_launcher” />

فایل Main.java :
package ir.AndroidCode.intent;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
public class Main extends Activity {
@Overridepublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

ImageView ax = (ImageView) findViewById (R.id.imageView1);
ax.setImageResource(R.drawable.androidcode_logo);
}
}

منبع:http://www.maximumtechnic.com/index.php?pid=2&op=2&id=1858

اشکال زدایی (debug) برنامه
تابحال تو دو تا از آموزش ها نشون داده شده که چگونه از DDMS برای مشاهده واقعی گزارشات ثبت شده (log) مربوط به برنامه که ناشی از دستگاهاتان یا شبیه‌سازتان، استفاده کنید. این کار بهتون کمک میکنه که بتونید خطاهای برنامه‌تونو رفع کنید یا فقط ببینید چه اتفاقی داره در حال اجرا می‌یفته.
در این مطلب می‌خوایم یه مقدار بیشتر به روش‌های خطایابی های قدیمی بپردازیم.
۱٫ اول یه پروژه جدید ایجاد کنید.
۲٫ میریم سراغ فولدر res بعد layout ، فایل activity_main.xml رو باز می‌کنیم، از قسمت pallette یه TextViewو Button و EditText می‌کشیم میاریم رو صفحه. البته TextView معمولا به صورت پیش فرض هست(همون HelloWord).

و برنامه رو ذخیره می‌کنیم.
۳٫ حالا اگر بخوایم برنامه مونو اشکال زدایی کنیم، باید یه چیزی به manifest اضافه کنیم که اجازه این کارو بهمون بده.
پس فایل Androidmanifest.xml رو باز می‌کنیم و رو زبانه Application کلیک می‌کنیم.
می‌تونیم مشخصه‌ی debuggable رو همون بالا ببینیم. اگر بخوایم برنامه‌مونو به اشکال زدای ایکلیپس متصل کنیم، باید این مشخصه رو فعال(true) کنیم.

۴. می‌خوایم تو فایل جاوای برنامه مون اعلام کنیم که در صورت فشردن دکمه چیکار کنه. پس با این کد یه نمونه از دکمه می‌سازیم و به دکمه‌ای که قبلا رو صفحه گذاشته بودیم متصل می‌کنیم.
Button dokme = (Button)findViewById(R.id.button1);
و بعد تابعی که قراره موقع کلیک دکمه صدا زده بشه رو می‌سازیم.
dokme.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});

۵. روی DDMS کلیک کنید و LogCat رو ببینید. البته بدون رفتن تو DDMS هم می‌تونید LogCat رو ببینید، از منوی که پایین ایکلیپس قرار داره می‌تونید پیداش کنید. LogCat در واقع هر چیزی رو که تو دستگاه اندروید در حال وقوعه، گزارش می‌کنه. پس به ازای هر ضربه ای که به صفحه ی دستگاهتون میزنید، اگر کار خاصی انجام بدید، شروع میکنه به ساختن اطلاعات گزارشی. ولی ما می‌تونیم اطلاعاتی رو که خودمون درباره برنامه‌مون می‌خوایم هم اونجا قرار بدیم.

۶. پس به فایل جاوا برمی‌گردیم. اینجا از کلاس Log که تو بسته ی android.util هست، استفاده می‌کنیم.
تو این کلاس چندتا تابع وجود داره که می‌تونیم ازشون برای تهیه گزارش از هرچیزی تو LogCat استفاده کنیم. مثلا تابع d یه پیغام اشکال زدایی ارسال می‌کنه و ورودی‌هاش یه برچسب(tag) و یه پیغام(msg) هست. البته اگر بخوایم یه استثنایی رو هم گزارش کنیم، میتونیم یه شیء throwable رو به عنوان ورودی بهش بدیم.
همچنین تابع e رو داریم که برای گزارش استثناء بکار می‌ره، تابع i یه پیغام اطلاعاتی و تابع v پیغام طولانی رو گزارش می‌کنه. w هم برای اخطاره. و اما جالب ترین چیزی که اینجا وجود داره، wtf هستش که مخفف اینه: What a Terrible Failure یعنی چه خرابی وحشتناکی و بیانگر چیزیه که انتظار نداشتیم تو سیستم اتفاق بیفته.

حالا ما می‌خوایم از تابع d استفاده کنیم. تو قسمت tag هر چیزی می‌تونه باشه، فقط باید یه جوری باشه که بتونیم از بین گزارشای دیگه توی LogCat تشخیصش بدیم. من اینجا با حروف بزرگ، سه بار می‌نویسم A. به عنوان پیغام هم اعلام می‌کنم که دکمه کلیک شده.
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d(“AAA”, “dokme feshorde shode”);
}
۷٫ کاری که من میخوام انجام بدم اینه که یه نقطه توقف (break point) به قطعه کد بالا اضافه کنم، بطوریکه اجرای برنامه رو تو اون نقطه متوقف کنه و به ما اجازه اشکال زدایی (debug) بده. به ستونی که سمت چپ کدتون هست توجه کنید. روی اون ستون، دقیقا روبروی خط سوم، دوبار کلیک کنید تا یه break point ایجاد بشه. مطمئنا هر کدوم از شما که قبلا کدش رو دیباگ کرده، این کارو انجام داده.

و بعد اون علامت دیباگ بالای صفحه رو میزنیم.
و گزینه اول، یعنی Android Application رو انتخاب می‌کنیم.

۸. تو شبیه‌ساز اول یه پیغام نشون میده مبنی بر اینکه منتظر اشکال زدا (Debugger) بوده.

در واقع منتظر اشکال زدای ایکلیپس بوده که به برنامه‌مون متصل شه. یه کمی صبر کنید متصل می‌شه.
وقتی رو دکمه ای که ساختیم کلیک کنیم، میبینیم که خودش ما رو می‌بره به قسمت debug توی ایکلیپس.

البته بسته به اینکه قبلا رو ایکلیپس چه کارایی انجام دادید، ممکنه یه پیغام نشون بده و ازتون بپرسه که آیا میخواید به قسمت اشکال زدا (debug) برید یا نه؟ که فقط کافیه بله رو بزنید.

۹. اگه یه نگاهی به logcat بندازید، متوجه می‌شید که پیغاممون رو گزارش نکرده. به خاطر اینکه برنامه مون رو تو اون نقطه متوقف کرده. پس رو علامت ادامه کلیک می‌کنیم تا اجرا ادامه پیدا کنه و اینجاست که می‌بینید پیغاممون گزارش می‌شه.

ستون Tag تو LogCat در واقع نشون دهنده‌ی اینه که کدوم فرایند، یا کدوم برنامه این پیغام رو ارسال کرده.

۱۰. یه چیز دیگه که باید درمورد LogCat بهش توجه کنیم، اینه که مقدار عظیمی از اطلاعات رو، درمورد هر اتفاقی که تو دستگاه می‌افته، گزارش می‌کنه. ولی اگه بخوایم که فقط اطلاعات مربوط برنامه مون گزارش بشه چی؟
کاری که باید انجام بدیم اینه که یه فیلتر تنظیم کنیم. پس روی علامت که اون بالاست، کلیک می‌کنیم. و من اسم فیلترمو میذارم A و بهش میگم اون گزارش هایی رو نشون بده که با برچسب AAA علامت گذاری شدن.

۱۱٫ همه این کارایی که انجام دادیم، یه روش قدیمی برای اشکال زدایی کد بود. و اما در مورد واسط کاربری، یه ابزار فوق العاده تو بسته ی SDK هست که این امکان رو برمون فراهم می‌کنه تا بتونیم مشکلات مربوط به صفحه‌بندی‌ها (layout) و در واقع واسط کاربری بپردازیم.
بنابراین فعلا رو علامت کلیک میکنیم که ارتباط دیباگر قطع شه.
به محل نصب android sdk می‌ریم یعنی پوشه ی android-sdk رو باز می‌کنیم و بعد به پوشه ی Toolsمی‌ریم. ابزار مورد نظرمون یه batch فایله که اسمش هست hierarchyviewer. روش دوبار کلیک میکنیم. تو مک خودش برنامه رو از طریق command line باز می‌کنه.
hierarchy به معنی سلسله مراتبه. کاری که این ابزار انجام می‌ده اینه که تمام فرایندها یا برنامه هایی رو که روی دستگاهمون در حال اجرا هستند، نمایش میده. الان دستگاهمون همون شبیه‌سازه.

۱۲٫ برنامه‌های آماده‌ی اشکال‌زدایی تو hierarchyviewer نشون داده می‌شه. برنامه‌ای می‌خوایم رو انتخاب می‌کنیم و بعد هم گزینه Load View Hierarchy رو می‌زنیم.

کاری که انجام می‌ده اینه که می‌ره و واسط کاربری برنامه‌مونو بررسی می‌کنه و اونو در قالب درختی نشون می‌ده. می‌تونیم تصویر رو بزرگ و کوچک کنیم و در واقع ساختار برنامه مون رو مشاهده کنیم.

الان ممکنه کنجکاو بشید که اون سه تا دایره ی رنگی چی هستن؟ در واقع برای نشون دادن performance یا همون سرعت عملکرده و سه مرحله هم واسش وجود داره. اولی اندازه گیری (measure)‌ هستش که میزان فضای مورد نیاز رو اندازه می‌گیره. مرحله ی دوم صفحه‌بندی (layout) هستش که چیزایی که داریم رو صفحه‌بندی می‌کنه و مرحله ی سوم هم رسم کردن (draw) نام داره که طراحی رو روی صفحه رسم می‌کنه. و واضحه که اگر رنگ همه این دایره ها سبز باشه، بهتره، که اینم فقط به بقیه ی viewهای برنامه تون بستگی داره. ولی اگر رنگشون زرد یا قرمز باشه، خوب نیست (واضحه که قرمز بدترین حالت رو نشون میده) و شما باید این نقاط رو به خاطر بسپارید و مراقبشون باشید که خرابی به بار نیارن.

۱۳٫ همه ما هنگام ساخت یه برنامه اندروید دوست داریم نمایی که از سلسله مراتب برنامه مون می‌بینیم،در ساده ترین شکل ممکن باقی بمونه و نمی‌خوایم که کلی صفحه‌بندی‌های تو در تو داشته باشیم. حالا اگه رو مستطیل مربوط به دکمه‌مون کلیک کنیم، یه قاب باز می‌شه که کنترل دکمه اصلی توی اون قاب نمایانه.

همچنین می‌تونیم تو قسمت property که سمت راست قرار داره، همه اطلاعات مربوط به این دکمه، از جمله اندازه و مکان قرار گرفتن و … رو با جزئیات کامل مشاهده کنیم.
http://www.maximumtechnic.com/imag…/farzin/pic/u/android.jpg

۱۴٫ این دفعه اگه رو مستطیل مربوط به دکمه‌مون دو بار کلیک کنیم، یه پیش نمایش ظاهر می‌شه که می‌تونیم بطور زنده آن را ببینیم دکمه مون با پشت زمینه سیاه یا سفید چه شکلی میشه یا یه سری اطلاعات اضافه‌تری رو ببینیم.

بهتون پیشنهاد میکنم حتما hierarchyviewer رو باز کنید و سلسله مراتب طراحی‌تونو توش ببینید، چون این ابزار میتونه برای بهبود عملکرد برنامه‌تون خیلی مهم باشه.

۱۵٫ ابزارهای دیگه ای هم وجود دارند که به همین خوبی هستند. این تصویر سایت SDK، زبانه ی Dev Guide، قسمت Debugging هستش. اگر شما واقعا به یه ردیابی عملکرد با جزئیات بالا برای برنامه تون نیاز دارید، یه ابزار به نام TraceView وجود داره که می‌تونه این کارو انجام بده. این ابزار حتی یه چیزی بیشتر از یه ابزار پیشرفته‌ست، به خاطر همینم ما فعلا خیلی به نمی پردازیم.

اما این ابزار یه نمایشی از یه نمودار زمانی بهتون می‌ده که نشون می‌ده کد شما تو کدوم زمان تو باریکه قرار گرفته. شما میتونید این کار رو با اضافه کردن یه سری اطلاعات مربوط به ردیابی، تو کدتون، انجام بدید.

تاکید می‌کنم که اگر شما با مشکلات اساسی در برنامه هاتون روبرو می‌شید، یا دارید برنامه ای می نویسید که عملکرد خوب جز اولویت‌های بالای اونه، TraceView ابزاریه که خیلی می‌تونه کمکتون کنه.

واحدهای اندازه‌گیری:
وقتی که برای اندازه‌های مختلف صفحه می‌خواهیم برنامه درست کنیم، اولین چیزی که لازمه بدونیم واحدهای اندازه‌گیری در اندرویده، تا بتونیم طوری برنامه رو توسعه بدیم که تو اندازه صفحه‌های مختلف به درستی نمایش داده بشه.:
۱.خوب برای اینکه بهتر متوجه بشیم، یه پروژه جدید در ایکلیپس می‌سازیم.:
از فولدر res زیر شاخه layout و activity_main.xml رو باز می‌کنیم و محیط گرافیکی اون برامون باز می‌شه. به طور پیش‌فرض صفحه‌بندی نسبی (RelativeLayout) برای همه پروژه‌ها در نظر گرفته شده. حالا اگه روی activity_main.xml کلیک کنیم می بینیم که در اولین خط نوشته RelativeLayout یعنی نوع صفحه بندی نسبی است. :
۲.حداقل تنظیماتی که هر شی در اندروید نیاز داره، ارتفاع و عرض در صفحه‌بندیه. :
باید عرض و ارتفاع صفحه بندی به صورتی باشه که تمام فضای والد خودش رو پر کنه (fill_parent) یعنی تمام صفحه رو بپوشونه.:
حالا می‌تونیم به قسمت گرافیکی activity_main.xml بریم و اون متن رو حذف کنیم و از منوی سمت چپ یه دکمه روی صفحه بکشیم و رها کنیم. وقتی به قسمت کد activity_main.xml می‌ریم می‌بینیم که اون هم برای خودش ارتفاع و عرض داره که با عبارت «wrap_content» پر شده، به این معنی که فقط به همون اندازه که نیاز داره، فضا اشغال می‌کنه.:
android:layout_width=”wrap_content” android:layout_height=”wrap_content”:
۳.برای دیدن مشخصات دکمه‌ای که ایجاد کردیم، از منوی سمت راست properties رو انتخاب می‌کنیم (اگه منوی properties رو ندارید، از منوی بالای ایکلیپس روی window بعد show view و other کلیک کنید و در زیرشاخه General گزینه properties رو انتخاب کنید تا براتون پنجره اش باز بشه و اگه دلتون بخواد می‌تونید اونو در سمت راست بذارید) این منو به ما اجازه می‌ده مشخصات هر چیزی که در قسمت گرافیکی انتخاب کردیم رو تغییر بدیم. الان می‌تونید رو دکمه‌ای که تو شکل مشخص کردم (پر کردن ارتفاع: toggle fill height) کلیک کنید تا بینید که در قسمت توضیحات درباره ارتفاع دکمه نوشته شده : match_parent به این معنی که طول اون شی رو انقدر اضافه می‌کنه تا به اندازه والدش بشه و در محیط گرافیکی می‌بینیم که همین طور هم شده. :
در کنار دکمه پر کردن ارتفاع (toggle fill height)، دکمه پر کردن عرض هم وجود داره، که اگه اون رو برای شی‌ای انتخاب کنید، باعث می‌شه شی تمام عرض والدش رو پر کنه.
قبل از GingerBread وقتی این دکمه رو می‌زدید، می‌نوشت fill_parent که در واقع همون کارو می‌کرد ولی الان اسمش رو عوض کردن گذاشتن match_parent
۴.حالا اگه بخوایم شی مورد نظرمون یه عرض و ارتفاع مشخصی داشته باشه باید چی کار کنیم؟ کاری که اکثر افراد می‌کنن اینه که یه مقدار با واحد pixel به اون شی اختصاص می‌دن. ولی یک پیکسل در دستگاه‌های مختلف اندازه متفاوتی داره مثلا یه شرکت دوست داره مقدار پیکسل رو یک دهم اینچ در نظر بگیره و یه شرکت دیگه یه مقدار متفاوتی رو، و این باعث می‌شه تا برنامه ما روی هر دستگاهی یه جور متفاوت باشه، به همین خاطر باید از یه واحد دیگه به نام dp استفاده کنیم که مخفف Device-Independent Pixle هست یعنی پیکسلی که مستقل از دستگاهه و برای همه دستگاه‌های اندروید یه چیز ثابته، قبلا sdk بهمون این اجازه رو می‌داد که هر واحدی که می‌خوایم رو استفاده کنیم، اما چون باعث می‌شد برنامه در دستگاه‌های مختلف متفاوت نمایش داده بشه، دیگه الان sdk به شما اجازه نمی‌ده واحد px رو بنویسید و خودش به dp تبدیلش می‌کنه.
۵.حالا اون دکمه رو از رو صفحه حذف می‌کنیم و یه متن (textView) به صفحه اضافه می‌کنیم، می‌خوایم اندازه متن رو تغییر بدیم. می‌تونیم از همون واحد dp استفاده کنیم. مثلا ۵۰ dp. ولی یه تنظیماتی در اندروید برای افرادی که چشمان ضعیفی دارند وجود داره که می‌تونن گزینه‌ای رو انتخاب کنن تا همه متن‌ها براشون درشت‌تر نمایش داده بشه، در چنین حالتی این متن ما همون اندازه خواهد موند و براشون بزرگ نمی‌شه، برای برطرف کردن این مشکل از واحد sp استفاده می‌کنیم، که مخفف Scale-Indepentent Pixle هست به معنی اینکه با توجه به مقیاسی که کاربر تنظیم کرده متن نمایش داده بشه و این واحد فقط برای متن به کاربرده می‌شه. و اگر کاربر تنظیمات گوشی اش رو دست نزده باشه، اندازه ۵۰ dp برابره ۵۰ sp خواهد شد، ولی برای افرادی که چشماشون ضعیفه بزرگتر نمایش داده خواهد شد.

صفحه‌بندی (layout)
خوب تا الان به طور پیش فرض از صفحه‌بندی نسبی (RelativeLayout) برای واسط کاربری پروژه‌هامون استفاده می‌کردیم. حالا می‌خوایم با انواع صفحه‌بندی آشنا بشیم.
۱.یه پروژه جدید در ایکلیپس بسازید و از فولدر res به زیر شاخه layout برید و activity_main.xml رو باز کنید. وقتی از منوی پایین روی activity_main.xml کلیک می‌کنیم و به کد مربوط به این فایل می‌ریم، می‌بینیم که در اولین خط نوع صفحه‌بندی تعیین شده.
۲.صفحه‌بندی نسبی که به طور پیش‌فرض برای تمام پروژه‌های اندروید قرار داره، بگونه‌ای که ما می‌تونیم، نسبت به دیواره‌های اطراف یا اشیائی که در صفحه قرار دارند، اشیا جدید رو قرار بدیم، الان همون متنی که تو صفحه هست رو حذف کنید و مثلا یه دکمه می‌خوایم به صفحه اضافه کنیم، وقتی دکمه رو از منوی سمت چپ می‌کشیم، هرجایی در صفحه که بخوایم قرارش بدیم، به طور نسبی مشخص می‌کنه اون دکمه چه وضعیتی با دیواره‌های اطراف داره، و بعد اون رو جایی که به نظرمون مناسبه رها می‌کنیم. (مثلا ۹۰ dp از بالا و ۹۰ dp از چپ فاصله داشته باشه) حتی وقتی دکمه رو روی صفحه رها می‌کنیم، هنوز برامون مشخص می‌کنه که اندازه‌های ما نسبت به دیواره‌های سمت چپ و بالاست (با دو تا فلش سبز رنگ)
۳.حالا بیاید یه RadioButton رو به صفحه اضافه کنیم، می‌تونیم طوری تنظیمش کنیم که نسبت اون رو با دکمه‌ای که قبلا اضافه کرده بودیم بسنجیم و قرارش بدیم. الان دکمه‌ی قبلی و این radioButton به عنوان یک مجموعه در نظر گرفته می‌شن، چون جای قرار گرفتن‌شون نسبت به هم سنجیده شده، حالا اگه جای دکمه‌ی اولی رو تغییر بدیم، radioButton هم به تبعیت از اون تغییر می کنه. (همین طور اگه radioButton رو تغییر بدید، دکمه اولی هم همراه‌ش تغییر مکان می‌ده.)
۴.حالا بیایید مقدار ثقل (Gravity) دکمه radioButton را به مرکز (center) تغییر بدیم، برای این کار روی دکمه‌ای که در تصویر مشخص شده کلیک کنید و center را انتخاب کنید، حالا مرکز ثقل مجموعه دو دکمه، به مرکز صفحه تغییر مکان می‌ده.
حالا اگه به داخل پنجره properties نگاه کنید، می‌بینید که مقدار ثقل (Gravity) هر دو دکمه به مقدار زیر تغییر پیدا کرده:
center_vertical|start
۵٫از انواع دیگه‌ی صفحه‌بندی می‌تونم به صفحه‌بندی خطی (LinearLayout) اشاره کنم، در این نوع صفحه‌بندی، همه چیز به صورت خطی پشت‌سرهم قرار می‌گیره. روی صفحه راست کلیک کنید، Change Layout و بعد هم LinearLayout، صفحه‌بندی خطی دو مدل داره افقی (Horizantal) یا عمودی (Vertical)، بیاید اول افقی رو انتخاب کنیم:
و قسمت کد activity_main.xml تغییر می‌کند:
یعنی به جای کلمه Relative نوشته شده Linear و یه شناسه جدید بهش داده شده، به همراه اینکه افقی بودنش مشخص شده.
۶٫برای اینکه بهتر متوجه بشیم این صفحه‌بندی چطور عمل می‌کنه، در قسمت گرافیکی، یه متن تو صفحه بندازید و یه دکمه از منوی سمت چپ بکشید و کنار متن رها کنین، خواهید دید که دکمه به صورت خطی کنار متن قرار می‌گیره و شما نمی‌تونید اون رو جای دیگه‌ای در صفحه (مثلا پایین صفحه) قرار بدید. این خطی قرار گرفتن همه چیز به صورت افقی است، می‌تونیم با کلیک روی دکمه‌ای که تو شکل مشخص شده، خطی بودن رو به صورت عمودی تنظیم کنیم. در این صورت هیچ چیز را نمی‌تونید در صفحه، افقی کنار هم قرار بدید و باید همه اشیا به صورت خطی و عمودی پشت‌سر‌هم قرار بگیرن.
بعد از خطی شدن به صورت عمودی، اگر به کد نگاه کنیم می‌بینیم که این کد در قسمت مشخصات صفحه‌بندی تغییر کرده و نوع جهت‌یابی رو به عمودی تغییر داده:
android:orientation=”vertical”
۷٫نوع بعدی، صفحه‌بندی چهارچوبی است (FrameLayout). یعنی هر چیزی برای خودش چهارچوبی داره که اون رو از بقیه جدا می‌کنه، به طوریکه حتی اشیا می‌تونن روی همدیگه بیوفتن، چون این نوع صفحه‌بندی طوری سازمان‌دهی نشده که اشیا رو مجزا از هم نگه داره.
برای تغییر به صفحه‌بندی چهارچوبی، روی صفحه راست کلیک کنید، Change Layout و بعد هم FrameLayout :
۸٫الان می‌تونید یه متن و یه دکمه رو، روی هم بندازید، می‌تونید روی دکمه کلیک کنید و از قسمت ثقل (Gravity) مرکز (center) رو انتخاب کنید و ببنید که دکمه مستقلا به مرکز صفحه منتقل شد.
این نوع صفحه‌بندی خیلی استفاده نداره، مگر اینکه مثلا شما می‌خواید با توجه به واکنش‌هایی که کاربر می‌ده، یه شی رو قابل رویت کنید و یه شی رو نامرئی کنید، مثلا می‌خواید یه سری عکس رو دنبال هم نشون بدید، می‌تونید با این صفحه‌بندی همه رو، روی هم بندازید و یکی یکی اونها رو قابل رویت بکنید. خلاصه این صفحه‌بندی در واقع هیچ کاری برای شما انجام نمی‌ده که شما رو مطمئن کنه اشیائتون به صورت مجزا از هم نشون داده می‌شن و همه زحمتش رو خودتتون باید بکشید. ۹٫نوع دیگه، صفحه‌بندی جدولی (TableLayout) هست، که خیلی هم می‌تونه مفید و کارراه‌انداز باشه. مفهومش خیلی شبیه جدول توی Excel یا HTML هست. راستی یه راه دیگه برای تغییر صفحه‌بندی اینه که مستقیما خود فایل activity_main.xml رو دستکاری کنید. (یعنی الان به جای کلمه Frame بنویسید Table)
۱۰٫در این صفحه‌بندی هر چیزی رو بندازید خودش به صورت سطرهای جدول در نظر می‌گیره و عرضشون رو به اندازه صفحه زیاد می‌کنه. اگر بخواید دوتا شی رو کنار هم در یه ردیف از جدول قرار بدید باید از منوی سمت چپ، گزینه layout رو بزنید و از توش TableRow رو انتخاب کنید و تو صفحه بندازیدش بعد تو این سطر می‌تونید چند تا شی رو کنار هم قرار بدید.
این نوع صفحه‌بندی خیلی مناسب درست کردن فرم عضویت در سایت و موارد مشابه.
۱۱٫بحث دیگه ای که وجود داره اینه که مثلا ما می‌خوایم تو صفحه دو تا دکمه با صفحه‌بندی خطی عمودی کنار هم باشن و سایر اجزای صفحه، با صفحه‌بندی نسبی(یا هرچیز دیگه‌ای که دلخواهتون هست) برای این کار باید صفحه‌بندی کلی‌مون همون نسبی باشه اما اون دوتا دکمه رو تو یه ظرف (container) بذاریم و صفحه‌بندی اون ظرف رو از نوع خطی عمودی تنظیم کنیم، برای این کار، اول هرچی تو صفحه هست رو پاک کنید، بعد با راست کلیک روی صفحه -> change layout بعد هم RelativeLayout. با این کار صفحه‌بندی کلی نسبی شد، حالا دوتا دکمه تو صفحه بندازید، یکی شون رو انتخاب کنید بعد کلید شیفت رو نگه دارید و اون یکی رو هم انتخاب کنید (دور هردوشون خط آبی بشه) بعد راست کلیک کنید و wrap in container رو بزنید.
نوع صفحه‌بندی این دو تا دکمه رو انتخاب کنید و براشون یه اسمی بذارید. بعد هم ok.
حالا دور مجموعه‌ی دو دکمه یه خط آبی کشیده (البته به راحتی می‌تونید هر کدوم از دکمه‌ها رو با کشیدن و رها کردن از تو مجموعه در بیارید)
با این کار توی activity_main.xml یه LinearLayout داخل تگ RelativeLayout با درست می شه:
اگه بخواهیم فاصله‌ی دو تا دکمه از هم صفر بشه پس مقدار margin هاشون رو صفر کنید. هر تغییر دیگه‌ای که دلتون بخواد به راحتی می‌تونید در آن اعمال کنین.
پس حواستون باشه قبل از این که یه صفحه به وجود بیارید درباره محتویات صفحه و اینکه چطور می‌خواید در صفحه چیده بشن خوب فکر کنید و صفحه‌بندی مناسبش رو انتخاب کنید. البته وقتی change Layout رو می‌زنید می‌بینید که انواع صفحه‌بندی خیلی زیاده، می‌تونید خودتون هر کدومشون رو امتحان کنید ولی صفحه‌بندی های اصلی همین‌ها بودن.

تا اینجا هرجا خواستیم از دکمه استفاده کنیم، از همون نوع سنتی و ساده‌اش استفاده کردیم، حالا می‌خوایم یاد بگیریم چطور از انواع دیگه‌ی دکمه استفاده کنیم.
۱. اول یه پروژه‌ی اندروید بسازید. بعد می‌تونیم در فایل activity_main.xml (در res->layout) از قسمت Palette انواع مختلف دکمه‌ها رو امتحان کنیم، الان اونی که روش نوشته off رو بکشید و روی صفحه بندازید.

شما می‌تونید به راحتی ظاهرش رو تغییر بدید و مناسب برنامه‌تون بکنید و می‌بینید که چقدر کار رو ساده کرده.
از انواع دیگه‌ی دکمه، دکمه‌ی رادیویی (radio) و دکمه‌ی علامت‌صحیح (checkbox) هستند که می‌تونید از تو palette وارد صفحه‌تون بکنید.

۲.وقتشه یاد بگیریم چطور به دکمه‌ها فرمان بدیم و برنامه‌ریزی کنیم. تو آموزش‌های قبلی یاد گرفته بودید که برای کنترل یک دکمه می‌تونید تابع مربوط به کلیک شدن‌شو تو خودش درست کنید، اما اون کار برای وقتایی مناسبه که یکی دوتا دکمه کلاً داشته باشید، اگر بخواید تعداد دکمه‌های بیشتری استفاده کنید بهتره از روش‌ دیگه‌ای استفاده کنید که الان توضیح می‌دم.
فایل MainActivity.java (در پوشه src) رو باز کنید، برای بهینه شدن استفاده از دکمه‌ها می‌تونیم به کلاس فعالیت (activity) بگیم که واسط گوش‌کننده‌به‌کلیک (onClickListener) رو پیاده‌سازی بکنه. یعنی کد شروع کلاس این طوری بشه:
public class MainActivity extends Activity implements OnClickListener {
با این کار ما می‌تونیم مستقیما تو کلاسمون به رخدادها واکنش نشون بدیم.
۳.وقتی قسمت implements رو به کلاسمون اضافه می‌کنیم، زیر OnClickListener خط قرمز می‌کشه، روش که ctrl+1 رو بزنیم یه گزینه میاره که (import ‘OnClickListener’ (android.view.view که وقتی این گزینه رو انتخاب می‌کنیم اونوقت زیر MainActivity خط قرمز می‌کشه، با فشردن ctrl+1 روی اون هم گزینه add unimplemented methods رو بزنید تا تابع مربوط به این پیاده‌سازی رو بسازه.

تابع جدیدی که ساخته می‌شه اسمش onClick هست و تمام دکمه‌هایی که در این فعالیت قرار دارند هر وقت که فشرده بشن، میان و این تابع رو اجرا می‌کنن، این طوری ما فقط یک تابع مدیریت رخداد کلیک‌روی‌دکمه می‌سازیم. توی این تابع باید بفهمیم کدوم دکمه کلیک شده که کار مربوط به همون دکمه انجام بشه.
۴.پس کاری که ما الان قراره انجام بدیم اینه که برای هر کدوم از دکمه‌ها باید گوش‌کننده‌به‌کلیک (onClickListener) رو سوار کنیم. و داخل تابعش به جای اینکه مثل قبل یه گوش‌کننده‌به‌کلیک رو توش نمونه‌گیری کنیم، می نویسیم this، یعنی همین فعالیتی که توش قرار داریم. تو این فعالیت هم فقط یه تابع onClick وجود داره که وقتی دکمه dokme رو بزنیم اونو اجرا می‌کنه.
Button dokme = (Button) findViewById (R.id.toggleButton1);
dokme.setOnClickListener(this);
۵.همین کارو برای بقیه‌ی دکمه‌ها باید انجام بدیم، خوبی این کار اینه که هی کلاس اضافه برای هر دکمه جداگانه تعریف نمی‌شه و کارآمدی و سرعت برنامه به میزان قابل توجهی بالا می‌ره.
توی تابع onClick ما باید اول شناسه (id) اون شی‌ای که این تابع رو فراخوانی کرده بدست بیاریم تا بتونیم با توجه به اون شناسه، کار مربوط به همون دکمه رو انجام بدیم. تابع گرفتن اون شناسه اینه : ()arg0.getId
می‌تونیم با گذاشتن عبارات شرطی مقدار ()arg0.getId رو بررسی کنیم. خوب مثلا بیاید برای اون دکمه‌ی خاموش روشنی که گذاشتیم یه عبارت شرطی بذاریم که اگه کلیک شد، تو LogCat بنویسه !dokmeye khamoosh roshan click shod
@Override
public void onClick(View arg0) {
if (arg0.getId() == R.id.toggleButton1) {
Log.d(“AC”,”Dokmeye khamoosh roshan click shod!”);
}
}

بعد از این کار وقتی شبیه‌ساز رو اجرا می‌کنیم و روی دکمه خاموش روشن کلیک می‌کنیم، پیغامی که تنظیم کرده بودیم توی LogCat نمایش داده می‌شه.
پس یه روش جدید یادگرفتیم که فقط با یک تابع گوش‌کننده‌به‌کلیک توابعمون رو مدیریت کنیم.
۶.یه نوع دکمه‌ی دیگه هم داریم به اسم دکمه‌ی‌عکس‌دار (ImageButton) که در palette در زیرشاخه Images & Media قرار داره که کاملا مشخصه که برای درست کردن دکمه‌ی عکس‌دار بکار می‌ره. این نوع دکمه رو وقتی می‌کشید روی صفحه و رها می‌کنید، ازتون می‌خواد که منبع عکسش رو انتخاب کنید که یا می‌تونید از عکس‌های سیستمی اندروید استفاده کنید یا عکس‌های دلخواه خودتون.

فهرست ها

یکی از مواردی که تو خیلی از برنامه می بینید فهرست هست. فهرست در واقع جایی به کار می‌ره که شما می‌خواید از بین یه سری گزینه تو فهرست یکی رو انتخاب کنید مثه انتخاب نام کشور خودتون در بین همه کشورها یا اینکه یه سری اطلاعات رو قراره تو قالب یک فهرست مشاهده کنین.
۱.خوب برای شروع یه پروژه اندروید بسازید. و در فولدر res روی فولدر values راست کلیک کنید و New بعد هم Other.

حالا از زیرساخه Android روی Android XML Values Files کلیک کنید و یه اسمی براش بذارید. من اسمشو می‌ذارم farzin.

۲.فایلی که ساختید براتون باز می‌شه، روی زبانه‌ی farzin.xml کلیک کنید تا خود فایل رو براتون باز کنه و این آرایه‌ی رشته‌ها رو توش وارد کنید. ما قراره این آرایه رو داخل یک فهرست قرار بدیم.

۳.خوب به فایل MainActivity.java (در src) می‌ریم، می‌بینیم که به صورت پیش‌فرض کلاس اصلی‌مون توسط کلاس فعالیت (activity) توسعه داده شده، اگر ما در یک فعالیت بخوایم فقط از فهرست‌ها استفاده کنیم بهتره به جای کلاس فعالیت از کلاس فعالیت‌فهرستی یا ListAcrivity استفاده کنیم، پس خط اولمون این شکلی می‌شه:
public class MainActivity extends ListActivity {
وقتی کد رو تغییر می‌دید زیر کلمه ListActivity خط قرمز می‌کشه روش ctrl+1 بزنید و گزینه (import ‘ListActivity’ (android.app رو بزنید.
۴.حالا به فایل activity_main.xml می‌ریم (در res->layout) و از ستون سمت چپ (Palette) زیرشاخه composite برید و نمای‌فهرستی (ListView) رو روی صفحه بکشید و رها کنید. باید به فهرستمون یه شناسه خاص بدیم که بتونیم تو فعالیت‌فهرستیمون بهش ارجاع بدیم. چون در هر فعالیت فهرستی فقط می‌تونیم شناسه مربوط به یک فهرست رو بدیم. زبانه activity_main.xml رو از نوار پایین انتخاب کنید و دنبال خطی بگردید که با android:id=” @android:id=”” list” ۵.به فایل MainActivity.java می‌ریم. برای اینکه مقادیر دلخواهمون رو به فهرست وارد کنیم، باید از تابع وفق‌دهنده‌فهرست ListAdapter استفاده کنیم. در واقع وفق‌دهنده مولفه‌ایه که داده مورد نظر رو می‌گیره و برای نمایش، شی‌مون رو وفق می‌ده. خوب از تابع ایجادوفق‌دهنده‌فهرست (setListAdapter) استفاده می‌کنیم و برای ورودیش یه نمونه جدید از آرایه‌ی‌وفق‌دهنده (ArrayAdapter) می‌سازیم. کاری که این آرایه می‌کنه اینه که آرایه‌ای از اطلاعات رو می‌گیره تا بتونه در فهرست ما نشون بده. برای درست کردن آرایه‌ی‌وفق‌دهنده سازنده‌های مختلفی وجود داره، سازنده‌ای که استفاده می‌کنید بسته به نوع اطلاعاتی داره که برای فهرستتون تهیه کردید. خوب مثلا اگه یه فهرست سفارشی درست کردیم که فقط یه متن معمولی نیست، می‌تونیم از شناسه منبع اون که به صورت نمای‌متنی (TextView) ذخیره شده استفاده کنیم. ولی چون ما اینجا می‌خوایم یه متن ساده رو به فهرستمون بفرستیم از این سازنده استفاده می کنیم که به عنوان ورودی ۳ تا مورد رو می خواد: محتوا، شماره منبع (که در اینجا همون صفحه‌بندیه) و شماره‌منبع‌نمای‌متنی.
ArrayAdapter (Context context, int resource, int textViewResourceId)
۶.برای محتوا کافیه کلمه this رو بنویسیم به معنی اینکه برای محتوا به همین فعالیت‌فهرستی ارجاع بشه، نوع این اطلاعات هم آرایه‌ای از رشته است که از همون فایل xml ای می‌یاد که ابتدای این آموزش ساختیم. برای منبع هم چون یه منبع خاص نساختیم می‌تونیم از منابع داخلی خود اندروید استفاده کنیم. android.R.layout.simple_list_item_1 فقط یه نمای‌متنی ساده است، اگه می خواستیم از یه فهرست سفارشی و خاص استفاده کنیم باید خودمون نمای‌فهرستی اش رو می‌ساختیم. (که در آموزش بعد یادخواهیم گرفت)

۷.برای گرفتن شماره منبع نمای‌متنی از تابع getResources استفاده می‌کنیم، این تابع تمامی منابع موجود در پروژه‌مون رو تهیه می‌کنه.بعد تابع تهیه‌ی‌آرایه‌ی‌رشته‌ای (getStringArray) رو صدا می‌زنیم و به عنوان ورودی باید شناسه آرایه‌ی رشته‌ای که تو فایل farzin.xml ساختیم رو بدیم: (بعد زیر ArrayAdapter خط قرمز می‌کشه روش ctrl+1 رو بزنید و گزینه import رو انتخاب کنید)
setListAdapter (new ArrayAdapter (this,
android.R.layout.simple_list_item_1,
getResources ().getStringArray(R.array.daneshgah)));
۸.تمام این کارا ممکنه یه کمی پیچیده به نظر برسه ولی وقتی علت هر قطعه کد رو متوجه بشید براتون آسون می‌شه، تو این آموزش یاد گرفتیم که چطور یه فهرست ساده درست کنیم، تو آموزش بعدی یاد می‌گیریم که چطور فهرست سفارشی (customise list) درست کنیم.
این هم نمایی از همین فهرستی که درست کردیم در شبیه‌ساز:

نکته : اگر کلمات فارسی به صورت جداجدا در شبیه ساز نشون داده شد، باید شبیه‌سازتون از نسخه Android 3.0 بالاتر باشه (قسمت Target Name در Android Virtual Device Manager)

آموزش ها همچنان ادامه دارد
فرزین نجفی پور: مدیرعامل شرکت دانش پژوهان طلیعه ایرانیان

درباره ی فرزین نجفی پور

پژوهشگر برتر کشور در چند سال متوالی - مخترع برتر کشور - ثبت 61 اختراع کاربردی در زمینه های کشاورزی، آبیاری، الکترونیک، رباتیک و هوا فضا - دارای مدرک کارشناسی ارشد - ارایه بیش از 100 مقاله علمی - دریافت دهها تندیس ویژه علمی - دریافت بیش از 150 تقدیر نامه از وزارت خانه ها و مراکز علمی و پژوهشی - برپایی بیش از 150 نمایشگاه تخصصی اختراعات - پیشگام در دفاع سایبری عملی از حریم جمهوری اسلامی ایران

همچنین ببینید

چگونه پوست صورت خود را زیبا کنیم؟

اسیدهای میوه کارکردهای بسیاری برای پوست دارند. آنها می توانند همه کاربرای زیبایی پوست انجام دهند؛ ...