آموزش برنامه نویسی اندروید - قسمت ۲۸: آشنایی با فایل XML در طراحی رابط کاربری اپلیکیشن
1. معرفی XML
2. علت به کارگیری XML در توسعه اندروید
3. معرفی اجزای تشکیل دهنده یک layout در اپلیکیشن اندرویدی
4. آشنای با استاندارد UTF-8
5. معرفی namespace
6. نحوه نامگذاری namespace در سیستم عامل اندروید
پس از آشنایی با بخش های تشکیل دهنده یک Activity اصلی در اپلیکیشن های اندرویدی، در این آموزش قصد داریم تا با اجزای تشکیل دهندۀ یک فایل XML که تشکیل دهندۀ layout در اپلیکیشن ها است آشنا شویم.
XML چیست؟
واژه XML مخفف واژگان Extensible Markup Language به معنی "زبان نشانه گذاری قابل گسترش" است. این زبان برخلاف HTML که به منظور نمایش داده ها مورد استفاده قرار می گیرد، برای ذخیره سازی و انتقال داده به کار گرفته می شود. شاید از دلایلی که از XML برای برنامه نویسی layout در توسعه اندروید استفاده شده است بتوان به گسترش پذیری آن، سهولت استفاده، خوانایی آن هم توسط انسان و هم توسط سیستم اشاره کرد. از سوی دیگر یک رابط گرافیکی کاربر یا همان GUI که توسط XML ایجاد شده باشد به سادگی قابل تحلیل و نمایش دادن است اما این در حالی است که اگر دیگر زبان ها در ساخت یک GUI استفاده می شد، تحلیل و Compile و اجرای آن به مراتب نسبت به یک فایل XML پیچیده تر می بود.
معرفی اجزای تشکیل دهنده layout اولین پروژه اندروید
به منظور درک کامل XML بهتر است layout پروژه ای که در آموزش هشتم تحت عنوان My First Android Project ساختم را مورد بررسی قرار دهیم. برای این منظور فایل main.xml که زیرشاخه layout در فولدر res قرار دارد را باز می کنیم:
همانطور که در تصویر فوق مشاهده می شود، پس از باز کردن فایل main.xml در پایین صفحه با دو گزینه متفاوت رو به رو خواهیم گشت: گزینه اول که با یک بیضی قرمز رنگ نشان داده شده است Graphical Layout به معنی "ساختار گرافیکی" است که نمود گرافیکی یک فایل xml را نشان می دهد. در حقیقت اگر این گزینه انتخاب شده باشد ساختاری مشابه با همان چیزی را خواهیم دید که در یک دستگاه واقعی نمایش داده خواهد شد. گزینه دوم main.xml است که با یک بیضی سبز رنگ نشان داده شده است. در واقع با کلیک کردن روی این گزینه به کدهای XML تشکیل دهنده layout دسترسی پیدا خواهیم کرد:
- xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
به محض کلیک کردن روی گزینه main.xml با کدی مشابه کد فوق رو به رو خواهیم شد. خط اول نشانگر شماره نسخه XML است که معادل با 1.0 می باشد و از سوی دیگر نوع رمزگذاری آن معادل با UTF-8 می باشد. UTF مخفف واژگان Unicode Transformation Format به معنی "فرمت تبدیل یونیکد" می باشد(لازم به ذکر است که یونیکد به منزله استانداردی است که از طریق آن کاراکترها و اعداد و علائم در اکثر زبان ها نشان داده می شود). عدد 8 حاکی از آن است که این استاندارد از 8 بیت حافظه برای ذخیره سازی یک کاراکتر استفاده می کند.
xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
کدی که در قسمت فوق ملاحظه می شود به منزلۀ کد اصلی است که مسئول ساخت layout می باشد. کلید واژه LinearLayout به ساختار layout ما اشاره دارد که ساختاری خطی است. به عبارت دیگر عناصری که روی این layout قرار می گیرند به صورت خطی یکی پس از دیگری یا از بالا به پایین و یا از چپ به راست در کنار یکدیگر قرار می گیرند. دستور xmlns:android=http://schemas.android.com/apk/res/android یک namespace به معنی "فضای نام" است که این وظیفه را بر عهده دارد تا از تداخل Tag هایی که دارای شناسه هایی یکسان می باشند جلوگیری به عمل آورد.
namespace چیست؟
برای روشن شدن این مطلب نیاز است تا مثالی دیگری ذکر کنیم. کد زیر حاوی اطلاعات یک جدول در HTML است:
Apples Bananas
در این آموزش قصد نداریم تا Tag های زبان HTML را مورد بررسی قرار دهیم اما همین قدر لازم است بدانیم که تگ های
و
Room 5 8
کد فوق هم حاوی جدولی است که اطلاعاتی پیرامون یک Room به معنی "اتاق" را در خود جای داده است. اکنون فرض کنیم که می خواهیم این دو جدول را در برنامه ای با یکدیگر ادغام کنیم. مشکلی که هم اکنون پیش خواهد آمد این است که سیستم نخواهد توانست تشخیص دهد که منظور ما table بالایی است یا table پایینی، از این رو سردرگم خواهد شد.
برای رفع این مشکل می توانیم به سادگی از یک پیشوند استفاده کنیم که در اینصورت کدهای فوق به شکل زیر در خواهند آمد:
اکنون بدون هیچ مشکلی توانستیم دو جدول را با پیشوندهای مجزا با یکدیگر ادغام نموده و هر دو را در کنار یکدیگر بدون هیچ مشکلی قرار دهیم.
اما نکته ای که در اینجا حائز اهمیت است این است که هر موقع که در کدهای XML خود از یک پیشوند استفاده می کنیم نیاز است تا یک namespace یا همان "فضای نام" را برای پیشوند خود تعریف کنیم. به طور کلی namespace با قرار دادن دستور xmlns در اولین Tag ایجاد می گردد. ساختار کلی namespace به صورت xmlns:prefix="URI" است به این صورت که پس از دستور xmlns یک علامت : قرار داده سپس پیشوندی که قصد داریم از طریق آن Tag را از یکدیگر مجزا سازیم را نوشته که در مثال های فوق ما از پیشوندهای a و b استفاده کردیم سپس یک علامت مساوی قرار داده و مقابل آن آدرس یک URL را داخل علامت های “ “ قرار می دهیم. در حقیقت اگر بخواهیم کدهای ادغام شده فوق را با نوشتن namespace تکمیل کنیم می بایست کدهای ما به شکل زیر باشند:
حال با قرار دادن دو namespace یکی برای پیشوند a و دیگری برای پیشوند b یک نوع یکنواختی را در کد خود ایجاد کرده زیرا زمانیکه یک namespace برای یک عنصر اصلی که در اینجا
است ایجاد می کنیم، کلیه عناصر زیرشاخه آن نیز از همان namespace تبعیت خواهند کرد.استاندارد نامگذاری Namespace به این شکل است که نامی به شکل آدرس یک URL برای آن در نظر گرفته می شود و علت آن هم ایجاد نامی منحصر به فرد است و در صورتیکه مثلا آدرس http://www.w3schools.com/furniture را در یک مرورگر وب تایپ کنیم به طور حتم با پیغام 404 – The page cannot be found به معنی "این صفحه قابل یافتن نیست" مواجه خواهیم شد زیرا این آدرس حاوی هیچ گونه اطلاعاتی نمی باشد. لازم به ذکر است که این نام همواره می بایست به همین شکلی که ملاحظه می کنیم باشد و در صورتیکه آن را تغییر دهیم اپلیکیشن ما با مشکل مواجه خواهد شد.اکنون که با مفهوم namespace آشنا شدیم مجدد به کد خود نگاهی خواهیم انداخت:
xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
در کد فوق برای Tag مرتبط با
وظیفه Tag مرتبط با layout_width تعیین عرض صفحه است و وظیفه Tag مرتبط با layout_height تعیین ارتفاع صفحه می باشد و مقدار در نظر گرفته شده برای این دو Tag معادل با fill_parent می باشد. معادل مقدار fill_parent مقدار match_parent می باشد و این دو هیچ فرقی با یکدیگر ندارند و علت وجود این دو مقدار با عملکردی یکسان این است که شرکت گوگل پس از توسعه API 8 نام fill_parent را به match_parent تغییر داد تا ماهیت آن تا حدودی گویاتر شود(از آنجا که API به کار گرفته شده در این اپلیکیشنی که در آموزش هشتم ایجاد کردیم 2.1 است و به عبارت دیگر7 API است از مقدار fill_parent استفاده شده است). به طور کلی می توان گفت که fill_parent یا match_parent این وظیفه را بر عهده دارند تا کل فضای بیرونی صفحه ای که در آن قرار دارند را اشغال کنند. به عبارت دیگر زمانیکه مقدار Tag های layout_width و layout_height معادل با fill_parent یا match_parent باشد، این دستور را به اندروید می دهیم که این رابط گرافیکی کاربر که ایجاد می کنیم می بایست کل صفحه نمایش دستگاه را شامل شود.
پس از مطالعه این آموزش انتظار می رود بتوانیم به سؤالات زیر پاسخ بدهیم:
1. علت استفاده از زبان XML در توسعه اندروید چیست؟
2. عدد 8 در عبارت UTF-8 به چه چیزی اشاره دارد؟
3. چرا در توسعه UI از namespace استفاده می کنیم؟
4. آدرس موجود در namespace به کدام سایت اینترنتی اشاره دارد؟
5. فرق مابین fill_parent و match_parent چیست؟
6. چرا در این پروژه ای که ایجاد کرده ایم از مقدار fill_parent استفاده شده است؟
در آموزش آتی با اجزای تشکیل دهنده یک layout آشنا خواهیم شد.
