آموزش اندروید، فصل هشتم: آشنایی با چیدمان خطی یا LinearLayout (بخش اول)

در این فصل و چند فصل بعدی همه تمرکزمان را می گذاریم بر روی طراحی رابط کاربری. با چیدمان خطی (Linear Layout) و چیدمان وابسته (Relative Layout) آشنا خواهید شد و می توانید هسته و سنگ بنای اولیه یک برنامه خوب و عالی اندروید را بنویسید (یا بسازید).

قبل از این که مطالب این فصل را شروع کنید، بهتر است نگاهی دوباره بیاندازید به «آموزش اندروید، فصل چهارم: اولین برنامه اندروید» تا اگر چیزی را فراموش کرده اید، مجدداً یادآوری شود.

چرا چیدمان؟

هر صفحه در رابط کاربری اندروید، از عناصر فراوانی تشکیل شده است. به عکس های زیر دقت کنید:

divar-1

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

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

divar-2

در این عکس، منویی که کاربر از طریق آن شهر محل سکونت خود و نیز دسته بندی آگهی های مورد علاقه خود را انتخاب می کند، در یک منوی کشویی قرار داده شده و کاربر باید آن را از سمت راست بکشد تا نمایش داده شود و …

همه اینها به ما نشان می دهد که برنامه نویس باید بتواند رابط کاربری مورد نظر خود را به هر شکل که می خواهد بسازد و برای این کار اندروید ابزاری دارد به نام مدیر چیدمان یا Layout Manager. با کمک این ابزار می توانید مثلاً بگویید دکمه جستجو کجای صفحه قرار می گیرد.

از میان انواع Layout Manager ها دو «چیدمان خطی» (Linear Layout) و «چیدمان وابسته» (Relative Layout) از کارایی بیشتری برخوردارند و با ترکیب آنها با هم می توان تقریباً هر رابط کاربری پیچیده ای را ساخت.

در این فصل با چیدمان خطی آشنا می شوید.


چیدمان خطی:

برای شروع یک پروژه اندروید جدید در اکلیپس با نام LinearLayoutExample بسازید (امیدوارم هنوز یادتان مانده باشد!). حالا از شاخه res/layout فایل activity_main را باز کنید. این بار به جای رفتن به طراح گرافیکی، کدهای XML برنامه را باز کنید:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

همانطور که می بینید، صفحه از یک layout وابسته استفاده کرده است. کد صفحه را به شکل زیر تغییر دهید:

<LinearLayout 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"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

حالا یک صفحه داریم که چیدمان آن خطی است. حالا به قسمت طراح گرافیکی برگردید و یک دکمه را به صفحه بکشید و روی صفحه رها کنید:

ch8-linear-layout-add-button

دکمه را هر جای صفحه رها کنید، باز برمی گردد و سمت راست عبارت Hello Wolrd می نشیند. چرا؟ چون چیدمان خطی تصمیم می گیرد که عناصر را چگونه کنار هم بچیند. حال یک دکمه دیگر بگیرید و به صفحه بکشید:

ch8-linear-layout-add-button-2

دکمه جدید هم در سمت راست دکمه قبلی قرار گرفت! باز هم خود LinearLayout تصمیم گرفت که دکمه را کجا بگذارد! اگر همینطور به اضافه کردن دکمه ها ادامه دهیم چه اتفاقی می افتد؟:

ch8-linear-layout-add-button-4

همانطور که می بینید دکمه چهارم دیگر حتا جا به اندازه کافی ندارد و نمایش آن به شدت زشت و نامناسب است.

حالا ببینیم چه اتفاقی اینجا افتاده. چیدمان خظی همانطور که از نامش پیدا است، عناصر را به صورت خطی می چیند. از بالا سمت چپ به سمت راست. در ضمن اگر اندازه خاصی برایش تعریف شده باشد، از اندازه خودش بزرگ تر نمی شود! احتمالاً می پرسید که این LinearLayout اصلاً به چه دردی می خورد پس؟! تا آخر این فصل شکیبا باشید تا ببینید با همین layout ساده چه کارها که نمی شود کرد!

تغییر جهت LinearLayout: چیزی که تا به حال دیدید، یک LinearLayout خطی «افقی» است. اگر کد صفحه را به صورت زیر تغییر دهیم و ویژگی android:orientation را به LinearLayout اضافه کنیم، LinearLayout ما «عمودی» می شود، یعنی عناصر را از بالا سمت چپ به پایین می چیند:

<LinearLayout 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"
    tools:context="${relativePackage}.${activityClass}"
    android:orientation="vertical">
...

ch8-vertical-linear-layout

LinearLayout می تواند افقی یا horizontal و عمودی یا vertical باشد. اگر ویژگی android:orientation را برای یک LinearLayout تعریف نکنید، LinearLayout به صورت پیش فرض افقی در نظر گرفته می شود.

نکنه: حتا اگر Linearlayout شما قرار است «افقی» باشد، باز هم orientation را برایش بنویسید. این کار هم به خوانایی بیشتر کد کمک می کند و هم جلوی بروز اشتباهات بیشتر را می گیرد.

ترکیب چیدمان ها

یک قانون طلایی درباره چیدمان ها وجود دارد: «چیدمان ها به هر تعداد و با هر شکل می توانند با هم ترکیب شوند». مثلاً می توانید داخل یک LinearLayout عمودی، تعدادی LinearLayout خطی داشته باشید. به عکس زیر دقت کنید:

ch8-using-layout-inside-another-layout

در این عکس، نوار سبز رنگ یک چیدمان خطی عمودی است که در داخل خودش ۳ چیدمان دیگر دارد. این چیدمان های داخلی می توانند خطی باشند، عمودی یا افقی باشند یا از سایر Layout ها مثل چیدمان وابسته (RelativeLayout) باشند. این ترکیب کردن را می توان ادامه داد و بیشتر و بیشتر کرد. عکس زیر را ببینید:

ch8-using-layout-inside-another-layout2

در این جا، در  Layout  پایینی ۲ Layout دیگر قرار دادیم.

تا چه زمانی می توان این ترکیب کردن را ادامه داد؟ از نظر تئوری هیچ محدودیتی برای این کار وجود ندارد ولی از منظر واقعیت، هر گاه به پیچیدگی Layout اضافه می شود، کشیدن (render کردن) آن هم سخت تر می شود و Layout های پیچیده تر زمان بیشتری برای کشیده شدن نیاز دارند. دوم این که Layout های پیچیده تر، در برابر تغییر هم انعطاف کمتری دارند. مثلاً ممکن است بعد از مدتی کار با یک برنامه، نیاز باشد یک دکمه را به جایی در صفحه اضافه کنید. اگر Layout ساده باشد و بر مبنای اصول صحیح ساخته شده باشد، اضافه کردن یک دکمه به صفحه کاری ساده است اما گاهی اوقات ممکن است برای کوچکترین تغییری که می خواهید در صفحه اعمال کنید، مجبور شوید کل Layout را مجدداً طراحی کنید که معمولاً کاری طاقت فرسا است. نکته سوم این است که این روزها طراحی ها به سمت طراحی های ساده و تخت (flat) می روند. بنابراین شما هم تا حد امکان طراحی برنامه هایتان را ساده تر کنید و بدانید که «ساده، زیبا است» (Simple is beautiful).

سایر ویژگی های چیدمان خطی

اگر به تعریف LinearLayout در کد XML صفحه نگاه کنید، می بینید که LinearLayout ما علاوه بر android:orientation ویژگی های دیگری هم دارد:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
...
</LinearLayout>

(فعلاً ویژگی های غیر ضروری را پاک کردیم)

همانطور که در کد می بینید، دو ویژگی android:layout_width و android:layout_height دو ویژگی دیگر LinearLayout اند. android:layout_width عرض چیدمان ما و android:layout_height ارتفاع آن را مشخص می کنند:

ch8-layout-width-and-height

مقادیر مجاز برای دو ویژگی android:layout_width و android:layout_height این ها است:

  • fill_parent یا match_parent: از این مقدار برای وقتی استفاده می شود که می خواهیم LinearLayout مان به اندازه جایی که والد یا parent ش اجازه داده است بزرگ شود. اگر یک Layout والد نداشته باشد، این مقدار برابر با عرض یا ارتفاع صفحه نمایش خواهد شد.
  • wrap_content: از این مقدار وقتی استفاده می شود که می خواهیم یک Layout به اندازه ای بزرگ شود که تمام Layout ها و View های درونی اش، داخل آن جا شوند. اگر به عکس ۵ نگاه کنید، می بینید که آخرین دکمه جایی برای نمایش ندارد، چرا؟ چون Layout والدش اجازه ندارد عرض خود را بیشتر کند تا همه بچه هایش دیده شوند.
  • یک عدد صحیح با واحد dp یا dip: ممکن است بخواهید یک Layout عرض یا ارتفاع مشخصی داشته باشد. برای این کار، در مقابل android:layout_width و android:layout_height یک عدد صحیح قرار می دهید. این عدد صحیح می تواند واحدهای مختلفی داشته باشد ولی مناسب ترین آن ها dip است که به صورت مخفف dp هم نوشته می شود. مثلاً اگر بخواهید ارتفاع Layout تان ۱۲۰dip باشد، آن را به شکل زیر تعریف کنید:
android:layout_width="120dip"
or
android:layout_width="120dp"

dip چیست؟

اندروید بر روی دستگاه های متنوعی نصب می شود. در حال حاضر معمولاً گوشی های موبایل در ابعاد ۳ تا ۵ اینچ هستند. فبلت ها که دستگاه هایی بینابین گوشی ها و تبلت ها هستند، معمولاً از ۵ تا ۸ اینچ هستند و تبلت ها از ۷ تا ۱۲ اینچ. اگر تلویزیون های هوشمند را هم به این فهرست اضافه کنیم، ابعاد از ۳ اینچ تا حدود ۸۰ اینچ هستند! در کنار این موضوع، کیفیت صفحه نمایش (رزولوشن) دستگاه ها هم بسیار با هم متفاوت هستند. یک صفحه نمایش در یک اینچ مربع ۱۶۰ پیکسل دارد و دیگری ۴۶۰ پیکسل!

فرض کنید بخواهید برای ابعاد عناصر صفحه از پیکسل استفاده کنید. فرض کنید عکسی دارید به ابعاد ۲۰۰ در ۲۰۰ پیکسل. این عکس در صفحه نمایش های با رزولوشن های خیلی بالا و خیلی پایین مثل عکس زیر خواهد بود:

ch8-display-resolution-comparison

اندروید باید به نوعی طراحی شده باشد، که بتواند این طیف گسترده از ابعاد و رزولوشن های مختلف را پشتیبانی کند. در این گستردگی فراوان اعتماد کردن به واحدی به اسم پیکسل، اشتباه بزرگی است. اندروید برای غلبه بر این مشکلات واحد جدیدی را برای طول معرفی کرده است به نام dip یا Density Independent Pixel که به معنی «پیکسل مستقل از تراکم صفحه نمایش» است. در یک گوشی با تراکم پیکسلی (رزولوشن) پایین، یک dip برابر یک پیکسل است اما در یک گوشی با تراکم پیکسلی خیلی بالا، یک dip سه یا چهار پیکسل خواهد بود.


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

ch8-example-1-preview

در عکس فوق، Layout آبی رنگ، برابر کل صفحه است. بنابراین عرض و ارتفاع آن به شکل زیر تعریف می شود:

android:layout_width="match_parent"
android:layout_height="match_parent"

احتمالاً می خواهید که چیدمان اصلی صفحه عمودی باشد، پس برای این چیدمان orientation یا جهت تعریف می کنید:

android:orientation="vertical"

در نهایت فایل XML شما مشابه زیر خواهد شد:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

</LinearLayout>

تا اینجا Layout ابی رنگ را ساخته اید. حالا می خواهیم یک Layout (احتمالاً افقی) به ارتفاع ۶۴ dip و عرض match_parent بسازیم:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="64dip"
        android:orientation="horizontal" >
    </LinearLayout>

این Layout جدید داخل Layout قبلی قرار می گیرد:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="64dip"
        android:orientation="horizontal" >
    </LinearLayout>

</LinearLayout>

از آنجایی که هر دوی این Layout ها سفید رنگ هستند، ما نمی توانیم آنها را از هم تشخیص بدهیم. بنابراین بیایید رنگ پس زمینه (Background) آنها را تغییر دهیم. برای این کار یک ویژگی دیگر به هر دوی این Layout ها اضافه می کنیم و رنگ یکی را آبی و دیگری را سبز می گذاریم:

android:background="#کد هگزا دسیمال رنگ"

کد نهایی XML ما:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#0000FF">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="64dip"
        android:orientation="horizontal"
        android:background="#00FF00">
    </LinearLayout>

</LinearLayout>

نتیجه نهایی مشابه عکس زیر خواهد شد:

ch8-example-1-final


در فصل بعد با ویژگی های بیشتری از LinearLayout آشنا خواهید شد. نظرات و پرسش های خود را با ما در میان بگذارید!

facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmail

16 فکر می‌کنند “آموزش اندروید، فصل هشتم: آشنایی با چیدمان خطی یا LinearLayout (بخش اول)

  1. مجید

    این مطالب به این باقلوایی رو نمیشه هیچ جا پیدا کرد….ما که تو کتمون نمیرفت الان خوب داره جا میفته….تشکر فراوان

    پاسخ
  2. هادی محمدی

    سلام خدمت استاد ارجمند و کاربلد و همکار نازنینم
    واقعا پروسه آموزش عالی هستش
    باحوصله و همچنین نکات ریز به موقع!
    مانا باشی برادر
    قلم آموزشی تون همیشه روان …

    پاسخ
  3. Ali

    استاد واقعا مطالبون عالی هستش
    من خیلی ممنون میشم اگر این مطالب رو همیشه در اختیار عموم قرار بدید و لطفا هیچ وقت پاک نکید اجرتون باخدا انشالله

    پاسخ

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>