آشنایی با-User Interface UI(واسط کاربر) در اندروید
بسم الله الرحمن الرحیم
آشنایی با-User Interface UI(واسط کاربر) در اندروید
فصل سوم-بخش اول
شما در پایان فصل با موارد زیر آشنا می شوید :
- انواع View Group ها که شما می توانید View ها در آن قرار دهید
- چگونه می توانید تغییرات صفحه نمایش را کنترل و آنرا با دستگاه های مختلف سازگار کنید
- چگونه می توانید یک Ui را با برنامه نویسی ایجاد کنید
- چکونه می توانید رخداد های UI را کنترل کنید
در فصل دوم شما با Activity ها و چرخه زندگی آنها آشنا شدید. شما یاد گرفتید که کاربر با Activity با برنامه در تعامل است. خود Activity چیزی ندارد که به کاربر نمایش دهد شما باید از View ها و ViewGroup ها استفاده کنید. درا ین فصل شما با یاد خواهید که که چگونه یک UI را ایجاد کنید و همچنین یاد می گیری که چگونه تغییرات صفحه نمایش را در دستگاه های مختلف مدیریت کنید.
فهمیدن قسمت ها ی مختلف یک صفحه
ددر فصل دوم شما یاد گرفتید که قسمت های پایه ای یک برنامه کاربردی اندروید activityمی باشد.یک activity رابط کاربر UI برنامه رانمایش می دهد. که شامل widget هامی باشد مانندButtonوTextViewوEditTextها ....
به طور کلی شما UIرا در یک فایل xml تعریف می کنید.(مانندmain.xmlکه ر مسیر res/layout)که چیزی شبیه زیر می باشد.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello Android" />
</LinearLayout>
در زمان اجرا برنامه UIرا با متد onCreate() مربوط به کلاس activity بارگزاری می کنید.وهمچنین متد setContentView از کلاس activity استفاده می کنید.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
{
در طول کامپایل برنامه هر Ui فایل Xmlبه معادل کلاس Android GUI کامپایل می شوندکه صفات attributes بامتدهای نمایش داده می شوند.هرچند که ساختنUi با فایل xml آسان و راحت می باشد اما زمان های لازم داریدکه ui ها را در زمان اجرا وبه صورت داینامیک به برنامه اضافه کنید.که این موضوع را در بخشهای بعدی شرح می دهم.
Views and ViewGroups
یکactivityشامل Viewو viewGroupهامی باشد یکView یک widget می باشدکه در صفحه نمایش داده می شود .به عنوان مثال View ها : Buttonها, Labelها ومواردی از این قبیل می باشد.
Viewها از کلاس پایهandroid.view.View. مشتق شده اند.
در فصل 4 View ها ی رایج را شرح می هیم.
یک یا چند View می توانند در یک ViewGroup گروه بندی شوند.یکViewGroup (که خود یک View می باشد)یک طرح بندی (layout)را برای نمایش مجموعه ای ازViewها د ر صفحه فراهم می آورد.
به عنوان مثال ViewGroupها شامل LinearLayout and FrameLayout می باشد.ViewGroup ها از کلاس پایه android.view.ViewGroup. مشتق شده اند.
اندروید از ViewGroupها ی زیر پشتیبانی می کنند:
- LinearLayout
- AbsoluteLayout
- TableLayout
- RelativeLayout
- FrameLayout
- ScrollView
در بخش های زیر هر کدامViewGroups ها از را با جزئیات بیشتری شرح می دهیم
LinearLayout
LinearLayout به عنوان یک ViewGoupتمام Viewها رادر صفحه در یک ستون یا در یک سطر مرتب می کند.View ها می توانندهم به صورت عمودی و هم به صورت افقی مرتب شوند. برای اینکه متوجه شویدکه LinearLayout چه طورکار می کنددستورات زیر راکه عموما در فایل main.xmlمی باشد را ملاحظه کنید
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Mehrdad Javidi" />
</LinearLayout>
درفایل main.xml , elemet ریشه <LinearLayout> می باشدکه دربرگیرنده elementی <TextView> می باشد.
عنصر LinearLayout نحوه ای چیدمان View ها در صفحه کنترل می کند.
هر View و ViewGroupدارای مجموع ای صفت های (َAtriute) می باشد.
که برخی از صفات در جدول زیر شرح داده ایم
صفت |
توضیحات |
layout_width |
عرض viewیا ViewGoupراتعیین می کند |
layout_height |
ارتفاعViewیا ViewGoupراتغیین می کند |
layout_marginTop |
فضای اضافی بالای Viewیا View Group را تعیین می کند |
layout_marginBottom |
فضای اضافی پایین Viewیا View Group را تعیین می کند |
layout_marginLeft |
فضای اضافی سمت چپ Viewیا View Group را تعیین می کند |
layout_marginRight |
فضای اضافی سمت راست Viewیا View Group را تعیین می کند |
layout_gravity |
چگونگی قرارگیری Viewها را تعیین می کند |
layout_weight |
تعیینی می کند فضای اضافی در طرح بندی را چگونه بهViewهای اختصای دهد |
layout_x |
محورxرا برای ViewیاView Groupراتعیین می کند |
layout_y |
محورyرا برای ViewیاView Groupراتعیین می کند |
توجه کنیدکه بعضی از صفات فقط مخصوص Viewها و بعضی ها مخصوص ViewGoupمیباشد.به عنوان مثال صفات layout_weight and layout_gravity فقط زمانی که viewهادر LinearLayout or a TableLayout می باشد قابل اطلاق می باشند |
به عنوان مثال width عنصر <TextView> برابر width پدر که کل آن را در بر می گیرد(که در اینجا پدرش صفحه نمایش می باشد.)که مقدار ش برابربا ثابت fill_parent می باشد
برای ارتفاع (height)از ثابت wrap_content استفاده کرده ا ست.که به این معنی می باشد که ارتفاع برابر ارتفاع آن چیزی که در بر می گیرید (content) می باشد. (که در این موردtext می باشد) .اگر شما مایل نیستید کهTextView کل سطر را در بر گیرد شما می توانید layout_width با wrap_content تنظیم کنید.
<<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Mehrdad Javidi" />
در مثال بالا شما عرض (width) TextView برابر با طول متن درون آن قرار دادید
دستورات زیر را مشاهده کنید
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="This is a Test" />
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="onClick" />
</LinearLayout>
زمانی که size یک عنصر را تنظیم می کنید.شما می توانید از واحدهای اندازه گیری زیر استفاه کنید:
|
در اینجا شما width مربوط به TextView و button را به صورت مقادیر absoluteتعیین کرده اید در این مورد شما width مربوط به 100 density-independent pixelsو buttonرا160density-independent pixels به تنظیم کرده اید
قبل از اینکه شماببینید که Viewها در صفحه نمایش های مختلف چگونه نمایش داده می شوند.شما باید ابتدا متوجه شوید که اندروید چگونه انواع سایز ها و Desityهاتشخیص می هد.
شکل زیر صفحه نمایش یک Nexus S. را نشان می دهد
صفحه نمایش آن 4اینچ می باشد .وپهنای صفحه 2.4 اینچ می باشد.و resolution 480 (width)*800(height) pixel می باشد
480پیکسل را بر 2.4اینچ تقسیم می کنیم جواب بدست آمده
(pixel density)می باشدکه حدود 235dpiمی باشد.
همانطور که از شکل مشاهده می کنید pixel density صفحه نمایش را
برای انواع وسایل میتوان با resolution. و سایزصفحه بدست آورد.
اندروید 4 چگالی را تشخیص می دهد.
- Low density (ldpi) — 120 dpi
- Medium density (mdpi) — 160 dpi
- High density (hdpi) — 240 dpi
- Extra High density (xhdpi) — 320 dpi
دستگاه شما در یک از چگالی های لیست شده در بالا قرار می گیرید.به عنوان مثال Nexus S در قرار hdpi می گیریدچگالی پیکس pixel density آن 240 dpi می باشد
Htc در اینجا دارای صفحه نمایش 3.2 اینچی می باشدوresolutionآن 320*480 است
وچگالی پیکس pixel density آن180 dpi میباشد.
برای تست کردن این که Viewها تعریف شده در فایل xmlزمانی که در صفحه نمایش های متفاوت قرار می گیرند چگون مشاهد می شونددو AVDsبا resolutions وdensities. متفاوت ایجاد کنیدبه عنوان مثال در شکل های زیر سمت راست را Nexus S. نمایش می دهدکه دارای resolution ,800*480 وچگالی 235 می باشدوسمت چپ یک AVD دیگر(HTC) نمایش می دهد.که دارای resolution 320*480می باشد وچگالی180, می باشد
استفاده از واحدdp اطمینان را حاصل می کندکه View ها همیشه در قسمت راست علی رغم Densityصفحه نمایش داده شود(در اندروید مقیاس صفحه بهصورت اتوماتیک به Desityصفحه بستگی دارد)
استفاه از buttonبه عنوان یک مثال ,این button در یک صفحه 180dpiنمایش داده شده است(یک صفحه 180dpi مانند یک صفحه 160dpi عمل می شود ) که عرض آن 160 پیکسل می باشد. ودر یک صفحه 235dpi (مانند یک صفحه نمایش نمایش 240dpi عمل می شود ) داده شده است که عرض آن باید 240پیکسل باشد.
چگونگی تبدیل DP به PX در زیر فرمول تبدیل آمده است: Actual Pixel= dp*(dpi /160) کهi dpدراینجا یک از مقادیر120, 160, 240, or 320 می باشد در نتیجه در مورد Buttonدر صفحه 235dpi داریم 160*(240/160)=240px برای اطمینان از درست بودن این فرمول شما می توانید از متد getWidth() مربوطView به استفاده کنید
|
حال به جای dpاز px استفاه کنید و نتیجه را مشاهه کنید
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="100px"
android:layout_height="wrap_content"
android:text="This is a Test" />
<Button
android:layout_width="160px"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="onClick" />
</LinearLayout>
android:onClick=”onClick”/>
شکل سمت چپ Labelو button را در صفحهنمایش 235dpi مشاهده می کنید و سمت راست در 185dpi .
سایز ها را با px تعیین کرده ایم.اندروید هیچگونه عمل تبدیلی را انجام نمی دهد زیر سایز های داده شده سایز های واقعی داده می باشند. .اگر شما از px استفاده کنید Viewها درصفحه نمایش های با کیفیت dpiبالاتر کوچکتراز آنهای که دارای dpi کمتر هستند نمایش داه می شوند.
در مثال قبل شما می توانیدorientation را به تغییرvertical: دهید
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
orientation به صورت پیش فرض vertical, می باشد.اگر صفتandroid:orientation را به horizontal” تغییرهیدنتیجه به صورت زیر می شود
در LinearLayout, شما می توانید صفت های layout_weight and layout_gravity را به View ها که درون آن می باشند اعمال کنید
فایل main.xml را به صورت زیر تغییر دهید.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="left"
android:layout_weight="1" />
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center"
android:layout_weight="2" />
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="right"
android:layout_weight="3" />
</LinearLayout>
صفتlayout_gravity مکان قرار گیری View هارا مشخص می کند
در حالی که layout_weight فضای تقسیم شده را مشخص می کند.در مثال قبل فضابه صورت زیر بین 3 Button تقسیم شد.
16.6%= (1/(1+2+3) * 100)
33.3% =(2/(1+2+3) * 100)
50% =(3/(1+2+3) *100)
(ارتفاع آن تغییرکرد.به خاطر android:orientation="vertical">)
اگر orientatinoمر بوط LinearLayout را به تغییر horizontal, دهیم شما باید width مر بوط به Button را به را به 0dp تغییر هید .
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="left"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center_horizontal"
android:layout_weight="2" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="right"
android:layout_weight="3" />
</LinearLayout>
AbsoluteLayout
AbsoluteLayoutاین امکان را می هید که شما مکان دقیق هر View را تعیین کنید. فایل main.xml را به صوصرت زیر تغیر دهید
<AbsoluteLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<Button
android:layout_width="188dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_x="126px"
android:layout_y="361px" />
<Button
android:layout_width="113dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_x="12px"
android:layout_y="361px" />
</AbsoluteLayout>
شکل سمت چپ نتیجه را در یک AVD180dpi نشان می هد. که مکان View ها را با صفتها ها ی android_layout_x and android_layout_y تعیین کرده . مشکل AbsoluteLayout این است که زمانی که Viewها در وسایل با کیفیت تصویری متفاوت قرار می گیرند مکان آنها تغییر می کند شما برا تنظیم Ui هیچوقت از AbsoluteLayout استفاده نکنید.در نسحه های مختلف اندرویدپشتیبانی نمی شود.
TableLayout
TableLayout ,Viewها در سطر و ستونهای دسته بندی می کندشما از <TableRow> عنصر برای تعیین سطرهای جدول استفاد ه می کنید هر سطر می تواند شامل یک یا چند View باشد. و width مر بوط به ستونهای برابر بزرگترین View که در آن قرار دارد تنظیم می شود.
فایلmaixmlزابه صورت زیر تغییرهید
<?xml version=”1.0” encoding=”utf-8”?>
<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Comments"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<EditText
android:id="@+id/txtComments"
android:layout_width="fill_parent"
android:layout_height="170px"
android:textSize="18sp"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/btnSave"
android:layout_width="125px"
android:layout_height="wrap_content"
android:text="Save"
android:layout_below="@+id/txtComments"
android:layout_alignRight="@+id/txtComments" />
<Button
android:id="@+id/btnCancel"
android:layout_width="124px"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_below="@+id/txtComments"
android:layout_alignLeft="@+id/txtComments" />
</RelativeLayout>
شکل زیرخروجی دستورات بالا را نمایش می دهد.توجه کنید که در مثال قبل TableLayout. دارای 2 ستون و 4 سطر می باشد.
RelativeLayout
شمارا قادر می سازدتا مکان قرار گیری View ها را نسبت به هم تعیین کنید.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true" >
<ImageView
android:src = "@drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
</RelativeLayout>
توجه کنید هر Viewe که در RelativeLayout
قرار می گیرد دارای صفت های زیر می باشد.
- layout_alignParentTop
- layout_alignParentLeft
- layout_alignLeft
- layout_alignRight
- layout_below
- layout_centerHorizontal
مقدار هر کدام از این صفت ها IDمربوط به Viewمی باشد که به آن اشاره می کنیم می باشد.
FrameLayout
View های که در FrameLayout قرار می گیرد همیشه در بالا سمت چپ طرح بندی (Layout) قرار می گیرد.
فایل main.xml را به صورت زیر تغییر دهید.
<?xml version=”1.0” encoding=”utf-8”?>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true" >
<ImageView
android:src = "@drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="124dp"
android:layout_height="wrap_content"
android:text="Print Picture" />
</FrameLayout>
</RelativeLayout>
شما یک FrameLayout درون RelativeLayout. دارید
ودرون FrameLayout, شما یک imageViewدارید.
در این مثال شمادرون res/drawable-mdpi یک تصویربه نام"@drawable/ic_launcher دارید.
اگر شما یک Viewدیگر مثلا Button, به FrameLayout اضافه کنید View جدید با Viewقبلی overlapمی شود.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true" >
<ImageView
android:src = "@drawable/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="124dp"
android:layout_height="wrap_content"
android:text="Print Picture" />
</FrameLayout>
</RelativeLayout>
شما می توانید چنین View را به FrameLayout اضافه کنید . زمانی کاربرد دارد که بخواهید یک animate با چند تصویر ایجاد کنید و این تصاویر در هر لحظه فقط یک از آن ها نمایش اده شود.
ScrollView
شما را قادر می سازد یک لیست از View ها را که فضای بیشتر از فضای سخت افزار دارند را به کاربر نمایش دهید.
Scolliew فقط یک View یا یک ViewGoup در بر می گیرد . که به طورپیش فرض LinearLayout. میباشد
فایل main.xmlرا به صورت زی تغییر دهید
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="@+id/button3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 3" />
<EditText
android:id="@+id/txt"
android:layout_width="fill_parent"
android:layout_height="600dp" />
<Button
android:id="@+id/button4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 4" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 5" />
</LinearLayout>
</ScrollView>
زیر را EditText به صورت اتوماتیک Focus را می گیرد. Edit Text کل Activity را در بر می گیرد. (زیرا ارتفاع آن به 600dpi تنظیم شده است )
برای اینکه از focus اتوماتیک جلوگیری کنیم شما باید دو صفت را LinearLayout برای تنظیم کنید
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical" >
زمان های وجو دارد که شما می خواهید زمانی که بر روی یک EditText رفتیم keybordنرم افزاری نمایش داده نشود برای اینکار شما باید به فایل AndroidManifest.xml رفته و تنظیمات زیر را انجام دهید.
<activity
android:label=”@string/app_name”
android:name=”.LayoutsActivity”
android:windowSoftInputMode=”stateHidden” >
<intent-filter >
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
تغیر ORIENTATION
یکی از ویژگی های تلفن های هوشمندمدرن توانای آنهادر Switch کردن بین orientation ها می باشد.واندروی هم از این قاعده مستثنی نمی باشد.اندروید از دو orientations: پشتیبانی می کند portrait و landscape .به طور پیش فرض زمانی که شما بین orientationحرکت می کنید Activityجاری به طوراتوماتیک در orientation جدید نمایش داده میشود. همچنین زمانی که بین orientationها سویچ می کندمتد onCreate()اجرا می شود.
توجه:زمانی که بین Orietaionهاسویچ می کند ativityجاری از بین می رودودوباره ساخته می شود. |
توجه داشته باشید که زمانی کهView ها دوباره بر روی صفحه نمایش داده می شوندممکن است در مکان اصلی خوقرار بگیرند(وابسته به این کدام layoutقرار داه اید)
توجه کنیدکه در حال landscape ممکن است تمام فضای خالی سمت راست صفحه استفاه شود. در نتیجه ممکن است تمام View های که در پایین صفحه در حالت landscape پنهان شوند
به طور کلی شما می توانید 2 تکنیک را برا ی کنتر ل تغییرات orientation: صفحه نمایش استفاده کنید.
- Anchoring :بهترین را برای AnchorکرنView ها به 4 گوشه صفحه نمایش می باشد . زمانی که orientation صفحه نمایش تغییر می کند شمابه سادگی می توانیدAnchor کنید به 4 لبه صفحه نمایش .
- Resizing and repositioning:
Anchoring Views (چسباندن View ها )
Anchoring به سادگی می تواند توسط RelativeLayout. امکان پذیر باشد.دستورات زیر را ردر main.xmlکپی کنیدکه شامل 4 Button که در <RelativeLayout> قرار دارند.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Left"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Left"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Right"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout
توجه کنید که خصوصیات زیردر 4 Button دیده می شود
- layout_alignParentLeft:View را در قسمت چپ پدر(در بر گیرنده) خودقرار می هد
- layout_alignParentRight:View را در قسمت راست پدر خودقرار می دهد.
- alignParentTop: View را در قسمت بالای پدر خودقرار می دهد.
- alignParentBottom: View را در قسمت پایین پدر خودقرار می دهد.
- layout_centerVertical:از عمودی در وسط قرار می دهد
- layout_centerHorizontal: از افقی در وسط قرار می دهد
وقتی به حالتlandscape می رود نتیجه به صورت زیر می شود
Resizing and Repositioning
علاوه بر anchoring کردن View ها در صفحه نمایش یک راه ساده تر این است که Ui های متفاوتی را برای هر orientation صفحه نمایش ایجاد کنید. برای این کار شما برای هر orientation یک فایل ui با پسوند Xml در res/layout ایجاد می کنید. برای پشتیبانی از landscape شما یک پوشه جدید به نام layout-land دو فایل main.xml ایجاد می کنید.
به طور پیشفرض فایل main.xml در res/layout برا ی حات portrait تعریف شده است.
دستورات زیر را در فایل main.xml در Layout بنویسید.
<?xml version=”1.0” encoding=”utf-8”?>
<RelativeLayout
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
xmlns:android=”http://schemas.android.com/apk/res/android”>
<Button
android:id=”@+id/button1”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Top Left”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true” />
<Button
android:id=”@+id/button2”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Top Right”
android:layout_alignParentTop=”true”
android:layout_alignParentRight=”true” />
<Button
android:id=”@+id/button3”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Bottom Left”
android:layout_alignParentLeft=”true”
android:layout_alignParentBottom=”true” />
<Button
android:id=”@+id/button4”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Bottom Right”
android:layout_alignParentRight=”true”
android:layout_alignParentBottom=”true” />
<Button
android:id=”@+id/button5”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Middle”
android:layout_centerVertical=”true”
android:layout_centerHorizontal=”true” />
</RelativeLayout>
دستوارت زیر را در فایل main.xmlدر layout-land بنویسید
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Left"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Left"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Right"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/button6"
android:layout_width="180px"
android:layout_height="wrap_content"
android:text="Top Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button7"
android:layout_width="180px"
android:layout_height="wrap_content"
android:text="Bottom Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
زمانی که activity اجرا می شود و در حالت portrait می باشد شکل زیر نمایش د اده می شودکه دارای 5 Button می باشد.
زمانی که activityها به حات landscape می رود شکل زیر می باشد که دارای 7 buttton می باشد.
با استفاده از روش ,زما نی که orientation صفحه تغییر می کند. اندروی به صورت اتوماتیک XML مر بوط به orientation آن را استفاده می کند.
مدیریت تغیرات برای orientation صفحه نمایش
حالا که شما یاد گرفتید که چگونه 2 تکنیک را برای کنترل تغییرات درorientation صفحه نمایش به کار گیرید .حال بیاد یاد بگیرید زمانی که بینorientation حرکت می کنیم حالت Activity در چه وضعیت ها قرار می گیرید.
در مثال زیر رفتار یک activity را زمانی که orientation تغییر می کند را شرح می دهیم .
یک پروژه جدید به نام Orientations در Eclipse ایجاد کنید
دستورات زیر را در mian.xml اضافه کنید .
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/txtField1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout
دستورات زیر رادر اضافه کنید
package com.MehrdadJavidi.orientations;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("StateInfo", "onCreate");
}
@Override
public void onStart() {
Log.d("StateInfo", "onStart");
super.onStart();
}
@Override
public void onResume() {
Log.d("StateInfo", "onResume");
super.onResume();
}
@Override
public void onPause() {
Log.d("StateInfo", "onPause");
super.onPause();
}
@Override
public void onStop() {
Log.d("StateInfo", "onStop");
super.onStop();
}
@Override
public void onDestroy() {
Log.d("StateInfo", "onDestroy");
super.onDestroy();
}
@Override
public void onRestart() {
Log.d("StateInfo", "onRestart");
super.onRestart();
}
}
کلیدF11را بزنید تا در خروجی مشاهده کنید
در دو TextView متنی را واردکنید.
بافشار دان Ctrl+ F11 orietation مر بوط به صفحه نمایش را تغییر دهید.
مشاهده می کنید که متن در TextView اول هنوز وجود دارد در حالی که در TextView دوم متن خالی شده است
همچنین در پنجره LogCat نتیجه به صورت زیر مشاهده می کنید.
زمانی که Orietation صفحه تغییر می کند در پنجره logcat موار زیر را مشاهده می کنید.که نشان می هد activity نابود و دوباره ایجاد شده است
بسیار مهم هست که این رفتارهارا بدانید. زیرا شما نیاز دارید مطمئن شوید که کار های ضروری را برای نگه داری وضعیت activity قبل از تغییر Orientation انجام دهید . به عنوان مثال ممکن است متغییر های در activity جاری داشته باشید که عملیات های بر اساس آنها انجام شود.برای هر activity شما باید وضعیت های آن را در زمان های که لازم می باشد در متد onPause() ذخیره کنید. این متد,متدی است که هر زمان که Orietationتغییر می کند اجرا می شود.در قسمت بعدی راه های که شما می توانیدوضعیت ها را ذخیره نمایید را شرح می هیم..
یک دیگر از رفتار های که شما باید بدانید این است که تنها View ها که دارای نام هستند (دارای صفت android:idهستند)وضعیت آنها زمانی که بین Orientationهای مختلف حرکت می کنیم یا به عبارت دیگر زمان های که Activity از بین می رود و دوباره ساخته می شود به صورت خود کار نگه داری و بازیابی می شود.
نگه داری اطلاعات وضعیت (information State)زمانی که پیکر بندی تغییر می کند. به یاد داشته باشیدکه زمانی که یک Activityدوباره ساخته می شو د (recreated,) ممکن است وضعیت جاری از بین برود.زمانی که یک Activityاز بین می رود متد های زیر اجرا می شوند.
- onPause()- این متدزمانی که یک Activityاز بین می رود یا در حالت BackGround قرار می گیرداجرا می شود.
- onSaveInstanceState()- این متن هم زمانی که Activityاز بین می رود یا در حالت BackGround قرار می گیرداجرا می شود(تا اینجا شبیه onpause() می باشد).
به طورخلاصه شما می توانی برای نگه داری وضعیت جاری همیشه ازمتد onPause() استفاده کنید,وسپس شمامیتوانیدراه های خودتان رابرای نگهداری وضعیت activity استفادهکنید. از قبیل دیتابیس فایلهایinteralیافایلهایExteralو مواردی ازاین قبیل ..
اگرشما به ساگی میخواهید وضعیت یک Activityراذخیره و دوباره بازیابی کنید زمانهای که Activityدوباره ساخته می شود شمامیتوانیدمتدonSaveInstanceState() را دوباره به کارگیرید این متد یک شی Bundle که به عنوان پارامترآن می باشدرافراهم می آوردکه به وسیله آن شما می توانید وضعیت Activity راذخیره نمایید.
@Override
public void onSaveInstanceState(Bundle outState) {
/**---save whatever you need to persist---*/
outState.putString("ID", "1234567890");
super.onSaveInstanceState(outState);
}
زمانیکه یک ACtivty دوباره ساخته می شوداول متدonCreate() اجرامی شود وبه دنبال آن متدonRestoreInstanceState() اجرا می شودکه شمارا قادرمیسازد وظعیت هاکه در متد onSaveInstanceState() ذخیره کردهاید را دوباره بازیابی کنید
@ Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
/**---retrieve the information persisted earlier---*/
String ID = savedInstanceState.getString("ID");
}
اگرچه شما میتوانیدمتدonSaveInstanceState() استفاد ه کنید ولی بایدتوجه کنیدکنیدکه شی Bundleدارای محدودیت های می باشد.اگر شما میخواهیدداده های پیچیده تری را ذخیره کنیداین راه حل مناسبی نمی باشد.
یک متدکه شما می توانید استفاده کنید.متدonRetainNonConfigurationInstance() میباشد این متدزمانی اجرا می شودکه ازبین فتن یک Activityبه دلیل تغییر پیکربندی (confi guration change)باشد(ازقبیل تغییرorientation, صفحه نمایش و توانایی های صفحه نمایش )
@Override
public Object onRetainNonConfigurationInstance() {
/**---save whatever you want here; it takes in an Object type---*/
return("Some text to preserve");
}
نکته اینجااست که این متد یک Objectبر میگراند.و به شمااجازه میده که هر نوع داده های که میخواهیدرا برگردانید.برای Extractکردن داده ها شما می توانیدآن رادر onCreate() متدانجام دهید. بااستفاده از متد getLastNonConfigurationInstance()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("StateInfo", "onCreate");
String str = (String) getLastNonConfigurationInstance();
}
تشخیص تغییر کردن Orientation
زمانی های وجود داردکه مانیاز داریم در زمان اجرا تشخیص دهیم که Activity در کدام Orientation قرار دارد. برای تعیین این مور شما میتوانید از کلاس استفاده WindowManager کنید. در قطعه کدزیر نشان می دهیم که چگونه اینکار راانجام دهیم
import android.view.Display;
import android.view.WindowManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**---get the current display info---*/
WindowManager wm = getWindowManager();
Display d = wm.getDefaultDisplay();
if (d.getWidth() > d.getHeight()) {
/**---landscape mode---*/
Log.d("Orientation", "Landscape mode");
}
else {
/**---portrait mode---*/
Log.d("Orientation”", "Portrait mode”");
}
}
متد getDefaultDisplay() یک نمونه از شی Display را که صفحه نمایش دستگاه رانمایش می دهد برمیگراند.
شما می توانیدWidth و Height مربوط به دستگاه را برای Orietation جاری بست آوید.
کنترل کردن Orientationصفحه نمایش
زمان های وجود دارد که شما می خواهید مطمئن شوید که برنامه فقط در Orietation مورد نظرتان قرار نمایش داده می شود.
به عنوان مثال شمامی خواهیدیک بازی بنویسید که می خواهیددرحالت landscape نمایش داده شود در این مورد شما می توانید با برنامه نویسی توسط متد setRequestOrientation() از کلاس Activity این کار را انجام دهید.
import android.content.pm.ActivityInfo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**---change to landscape mode---*/
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
برای تغییر به حالت landscape از ثابت ActivityInfo.SCREEN_ORIENTATION_PORTRAIT استفاده کنید .در کنار متد setRequestOrientation() شما می توانیداز صفت android:screenOrientation در عنصر <activity> در فایل AndroidManifest.xml استفاده کنید
<?xml version=”1.0” encoding=”utf-8”?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”net.learn2develop.Orientations”
android:versionCode=”1”
android:versionName=”1.0” >
<uses-sdk android:minSdkVersion=”14” />
<application
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name” >
<activity
android:label=”@string/app_name”
android:name=”.OrientationsActivity”
android:screenOrientation=”landscape” >
<intent-filter >
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>
</manifest>