در قسمت قبل به صورت پایهای با طراحی LinearLayout آشنا شدید و چند مثال ساده را با هم پیاده کردیم. در این قسمت قبل داریم یک لایه پیچیده مانند یک ماشین حساب را طراحی کنیم.
ماشین حسابی که قصد داریم با LinearLayoutها طراحی کنیم در نهایت به شکل زیر خواهد بود:
پس از پایان کار طراحی پنل Component Tree به شکل زیر خواهد بود:
همانطور که در بالا میبینید این مثال بسیار پیچیده و تو در تو است، ولی از نظر اجرایی ارزش بالایی دارد و رسم آن تمرین بسیار خوبی محسوب میشود.
کل سورس این لایه را از لینک زیر دانلود کنید:
این سورس را دانلود و در مسیر res -> layout
پروژه خود Paste کنید تا بتوانید لایه نمایشی این ماشین حساب را در اندروید استودیو ببینید.
در اولین مرحله یک لایه LinearLayout با orientation افقی یا vertical اضافه میکنیم. در ادامه قصد داریم مرحله به مرحله با اضافه کردن پنج لایه اصلی ماشین حساب بالا را رسم کنیم. این پنج لایه اصلی که اضافه میکنیم همه LinearLayout و Horizontal هستند و layout:width آنها match_parent (تمام عرض عنصر والد) و layout:height آنها wrap_content (طول به میزان عناصر درون) است.
لایه اول برای باکس عرضی نمایشگر محاسبات: درون این لایه یک TextBox قرار میدهیم که سورس آن به شرح زیر است:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:height="48dip"
android:width="0dip"
android:layout_weight="1"
android:layout_marginBottom="80dip"
android:paddingRight="10dip"
android:gravity="center_vertical|right"
android:textSize="25dip"
android:background="#004a80"
android:textColor="#fff"
android:id="@+id/textView"/>
android:text به محتوای درون TextView اشاره میکند. در سطر پنجم ارتفاع المان 48dip و عرض آن 0 است. چرا عرض این المان صفر است؟
اگر به سطر هفت دقت کنید خاصیتی به نام android:layout_weight برابر یک قرار دارد که نشان دهنده وزن این TextView است. اگر یک المان درون لایه LinearLayout افقی قرار گیرد و عرض آن صفر باشد، میتوانیم با android:layout_weight به آن عنصر وزن بدهیم. اگر در یک LinearLayout افقی تنها یک عنصر قرار بگیرد هر عدد بزرگتر از صفری که به layout_weight بدهیم این المان به صورت تمام سطر در میآید.
اگر دو عنصر در کنار هم قرار داشتند و به هر کدام یک weight بدهیم، جمع weightها نسبت فضای اشغالی هر المان را معین میکند. مثلا اگر به دو المان یک بدهیم، هر کدام از المانها 50 درصد فضا را به خود اختصاص میدهند. اگر به یکی 1 و به دیگری دو بدهیم، اولی 33 در صد فضا و دومی 66 درصد فضا را به خود اختصاص میدهد.
در سطر هشت با خاصیت layout_marginBotton فاصله فضای بین TextView و عنصر پایین را 80dip تعیین کردیم.
در سطر نهم فاصله درونی TextView را از سمت راست 10dip قرار دادیم تا عدد به لبه TextView نچسبد.
در سطر دهم در gravity موقعیت عنصر را از نظر ارتفاع center_vertical و از نظر جهت right انتخاب میکنیم تا به شکل تصویر در بیاید.
در سطر یازدهم با textSize سایز نوشته، در سطر دوازدهم با background رنگ زمینه و در سطر سیزدهم با textColor رنگ نوشته را تعیین میکنیم.
در سطر چهاردهم android:id شناسه TextView را مشخص میکند که در قسمتهای بعدی به آن میپردازیم.
نکته: در لایههای بعدی نیازی به معرفی مجدد خاصیتهایی که در بالا توضیح دادیم وجود ندارد.
لایه دوم برای کلید CL: برای پیاده سازی این لایه به یک ترفند کوچک نیاز داریم. این لایه از چهار TextView تشکیل شده است که ارتفاع همه آنها 48dip، عرض آنها 0 و layout:weight آنها یک است. سورس را در ادامه ببینید:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="0dip"
android:height="48dip"
android:gravity="center"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="0dip"
android:height="48dip"
android:gravity="center"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="0dip"
android:height="48dip"
android:gravity="center"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CL"
android:id="@+id/textView36"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
سه TextView اول android:text و android:background و android:textColor و android:textSize ندارند. دلیل این امر این است که سه لایه اول مخفی باشند تا لایه چهارم که عبارت CL را در بر دارد به درستی نمایش داده شود. اگر در سورس کد دقت کنید تمام عناصر layout:margin برابر 4 دارند تا اندازه فاصله از لبههای عناصر به یک میزان باشد.
لایه سوم برای اعداد یک تا سه و منفی: این لایه مانند لایه فوق است با این تفاوت که سه TextView اول آن نمایش داده میشود و مخفی نیستند. سورس کد را در ادامه داریم:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:id="@+id/textView23"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:id="@+id/textView24"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
android:id="@+id/textView25"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:id="@+id/textView26"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
لایه چهارم برای اعداد چهار تا شش و مثبت: این لایه نیز مانند لایه فوق است. سورس کد این لایه عبارت است از:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4"
android:id="@+id/textView9"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5"
android:id="@+id/textView10"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="6"
android:id="@+id/textView21"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:id="@+id/textView22"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
لایه پنجم برای اعداد هفت تا نه، صفر، مساوی و ممیز: این لایه پیچیده تر از لایههای فوق است و درون خود لایههای متعددی را جای داده است. ساختار لایههای این بخش را در زیر میبینید:
در تصویر بالا میبینید در لایه اصلی LinearLayout (horizontal)
دو لایه LinearLayout افقی (vertical) و عمودی (horizontal) قرار داده ایم. لایه اول برای اعداد 7 تا 9 و عدد صفر و ممیز است. لایه دوم که از نوع عمودی است نیز در بر گیرنده علامت مساوی ماشین حساب است. سورس کد این دولایه به شرح زیر است:
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.75">
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.25">
</LinearLayout>
همانطور که در بالا میبینید، لایه اول vertical و لایه دوم horizontal است. layout_width و layout_height لایه اول wrap_content (بر اساس محتویات) است.
layout_width لایه اول wrap_content و layout_height آن match_parent (پر کردن بر اساس والد) است.
از آن جایی که LinearLayoutها عنصر width را ندارند، تنها layout_weight را برای لایه اول 0.75 و برای لایه دوم 0.25 قرار میدهیم. همانطور که در بالا گفتیم این weightها با هم جمع شده و هر عنصر به نسبت عددی که ما به آن دادیم وزن میگیرد.
طراحی لایه اعداد 7 تا 9 و صفر و ممیز: همانطور که در تصویر پنل Components Tree فوق میبینید این لایه خود از دو LinearLayout عمودی تشکیل شده است. به سورس این دولایه دقت کنید:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="7"
android:id="@+id/textView29"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8"
android:id="@+id/textView27"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9"
android:id="@+id/textView28"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="."
android:id="@+id/textView31"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_weight="0.33333"
android:layout_margin="4dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:id="@+id/textView32"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"
android:layout_weight="0.66666"/>
</LinearLayout>
</LinearLayout>
در بالا دو LinearLayout اصلی ارتفاعی برابر محتویات خود (wrap_content) و عرضی برابر کل عنصر والد خود (match_parent) دارند.
به هر کدام از سه TextView لایه اول weightای برابر یک میدهیم تا به یک میزان فضا اشغال کنند.
به دو TextView لایه دوم وزنهای 0.3333 و 0.6666 میدهیم.
کلید مساوی: برای پیاده سازی این کلید کافی است درون لایه ذکر شده در بالا که وزن 0.25 داشت یک TextView مانند زیر ایجاد کنیم:
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="="
android:id="@+id/textView30"
android:width="0dip"
android:height="48dip"
android:background="#004a80"
android:gravity="center"
android:textColor="#fff"
android:textSize="25dip"
android:layout_margin="4dip"/>
این تمرین با وجود پیچیده بودن از اهمیت بسیار بالایی برخوردار است و با یادگیری آن میتوانید بسیار راحت LinearLayoutها را پیاده سازی کنید.
در قسمت بعدی شروع به آموزش RelativeLayout میکنیم. با هیتوس همراه باشید.