سبد (0)

آموزش اندروید

  • پیش نیازها

    • Android 1.6 یا بالاتر

    مورادی که باید مطالعه کرده باشید

    • منابع برنامه
    • طراحی برای صفحات نمایش مختلف

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

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


    بیاموزهای این سرفصل

    READ MORE
  • اجزای یک صفحه

    همانطور که می دانید اکتیویتی پایه ای ترین جز یک برنامه ی اندرویدی است.اکتیویتی رابط کاربری برنامه ی شما را نشان می دهد که ممکن است شامل قسمت هایی مثل Buttonها, Lable ها, textBox ها,...باشد.معمولاً رابط کاربری را در یک فایل XML مثل main.xml که در پوشه ی res/layout قرار دارد تعریف می کنید.که شبیه کدهای زیر است: 

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
    <TextView
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:text=”@string/hello”
    />
    </LinearLayout>

    در زمان اجرا,شما رابط کاربری XML را در متد رویداد()onCreate کلاس Activity با استفاده از متد ()setContentView بارگذاری می کنید:

     

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    }

     در زمان کامپایل برنامه هر کدام از عناصر موجود در فایل XML به یکی از کلاس های GUI اندروید به همراه خصوصیاتی که بوسیله ی متدها تنظیم شده,کامپایل می شود.سیستم اندروید زمانی که اکتیویتی بارگذاری می گردد,رابط کاربری را ایجاد می کند.

    ایجاد رابط کاربری در فایل XML بسیار آسان است,اما گاهی نیاز است که رابط کاربری پویایی را در زمان اجرا ایجاد کرد(برای مثال زمانی که در حال ساخت بازی هستید) با این قابلیت شما می توانید رابط کاربری خود را در زمان اجرا ایجاد کنید.

    یک اکتیویتی شامل View ها و گروه های ابزاری نمایش می باشد.یک View ویجتی است که روی صفحه قرار دارد.نمونه هایی از Viewها مثل Button ها, Lable ها, TextBox ها را می توان نام برد.یک View از کلاس پایه ی android.view.View برگرفته شده است.یک یا چند View  را می توان با هم در یک گروه ابزار نمایش قرار داد.یک گروه ابزار (که خود نوعی از View ها است) فضایی را جهت چینش و مرتب سازی View ها فراهم می کند.به عنوان مثال یک گروه ابزاری شامل LinearLayout و FrameLayout ها هستند.یک گروه ابزار نمایش از کلاس پایه ی android.view.ViewGroup برگرفته شده است.اندروید از گروه ابزار نمایش زیر پشتیبانی می کند:

    • LinearLayout
    • AbsoluteLayout
    • TableLayout
    • RelativeLayout
    • FrameLayout
    • ScrollView

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

    LinearLayout

    LinearLayout ها View ها را در یک ردیف یا یک ستون چینش می کند.ابزار های نمایش می توانند به عنوان فرزند در LinearLayout به صورت افقی یا عمودی چیده شوند.

    برای اینکه ببینید LinearLayout ها به صورتی کار می کنند,تغییرات زیر را در فایل main.xml اعمال کنید:

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <LinearLayout
    xmlns:android=”http://schemas.android.com/apk/res/android”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
    <TextView
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:text=”@string/hello”
    />
    </LinearLayout>

    در فایل main.xml می بینید که عنصر ریشه <LinearLayout> است که عنصر<TextView> درون آن قرار دارد.عنصر <LinearLayout> اولویت نمایش ابزار های نمایشی که درون آن قرار دارند را کنترل می کند.هر ابزار نمایش یا گروه ابزارها یکسری خصوصیات عمومی به شرح زیر دارند:

    layout_width -- عرض ابزار نمایش یا ViewGroup را مشخص می کند.

    layout_height -- طول ابزار نمایش یا ViewGroup را مشخص می کند.

    layout_marginTop -- فضای اضافه ی لبه ی بالای ابزار نمایش یا ViewGroup را مشخص می کند.

    layout_matginBottom -- فضای اضافه ی لبه ی پایین ابزار نمایش یا ViewGroup را مشخص می کند.

    layout_marginLeft -- فضای اضافه ی لبه ی سمت چپ ابزار نمایش یا ViewGroup را مشخص می کند.

    layout_marginRight -- فضای اضافه ی لبه ی سمت راست ابزار نمایش یا ViewGroup را مشخص می کند.

     layout_gravity -- چگونگی قرارگیری ابزارهای نمایشی فرزند را مشخص می کند.

    layout_weight -- نشان دهنده ی فضای اضافی است که می تواند به ابزار نمایش اختصاص یابد.

    layout_x -- جهت افقی ابزار نمایش یا گروه ابزار را مشخص می کند.

    layout_y -- جهت عمودی ابزار نمایش یا گروه ابزار را مشخص می کند.

     بعضی از این خصوصیات تنها زمانی کاربرد دارند که ابزار نمایش در گروه ابزار خاصی قرار گیرد.به عنوان مثال خصوصیات layout_weight و layout_gravity فقط وقتی کاربرد دارند که یک ابزار نمایش در LinearLayout یا TableLayout قرار گیرند.

     برای مثال عرض عنصر <TextView> با استفاده از ثابت fill_parent تمام عرض والد خود یا صفحه نمایش را پر می کند.ارتفاع آن به وسیله ی wrap_content مشخص می شود و به این معنی است که ارتفاع این عنصر به اندازه ی ارتفاع محتویات آن یا ارتفاع متن است.اگر نمی خواهید که <TextView> تمام ردیف را اشغال کند,میتوانید خصوصیت layout_width را برابر wrap_content قرار دهید:


    < TextView
    android:layout_width=”wrap_content
    android:layout_height=”wrap_content”
    android:text=”@string/hello”
    />

     با استفاده از کد بالا ,عرض View به اندازه ی عرض متن موجود در آن تنظیم می شود.

    به کد زیر دقت کنید:

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
    <TextView
    android:layout_width=”105dp”
    android:layout_height=”wrap_content”
    android:text=”@string/hello”
    />
    <Button
    android:layout_width=”160dp”
    android:layout_height=”wrap_content”
    android:text=”Button”
    />
    </LinearLayout>

     در اینجا طول هردو عنصر TextView و Button را به وسیله ی مقادیر مطلق تنظیم کردیم.در این مثال عرض TextView معادل 100dp و عرض Button معادل 160dp در نظر گرفته شده است.

    واحدهای اندازه گیری

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

    • Density-independent pixel -- dp : :یک dp برابر است با یک پیکسل در صفحه نمایش 160dpi .این واحد اندازه گیری  برای تنظیم رابط کاربری شما مناسب است.صفحه نمایش 160dpi حالت پایه و پیشفرض برای اندروید محسوب می شود.برای نشان دادن واحد اندازه گیری می توانید از dp یا dpi استفاده کنید.
    • Scale-independent pixel --sp :مشابه dp است و برای تعیین اندازه فونت ها بکار می رود.
    • Point -- pt :یک واحد پوینت 1.72 اینچ است.که بر مبنای اندازه ی فیزیکی صفحه به دست می آید.
    • Pixel -- px : بستگی دارد به اندازه ی پیکسل در صفحه نمایش.استفاده از این واحد اندازه گیری توصیه نمی شود.چون ممکن است در دستگاه های مختلف با رزولوشن های مختلف اجرا نشود.

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

    • 120dpi --Low density             ldpi
    • 160dpi -- Medium density           mdpi
    • 240dpi -- High density            hdpi
    • 320dpi -- Extra High density           xhdpi

    هر دستگاهی در یکی از این دسته ها قرار می گیرد.برای مثال Nexus s در دسته ی hdpi قرار دارد چون چگالی آن نزدیک به 240 است.دستگاه HTC Hero دارای یک صفحه نمایش 3.2 اینچی با رزولوشن 320 در 480 است که حدوداً با چگالی 180dpi کار می کند.این دستگاه در دسته ی mdpi قرار می گیرد چون چگالی آن نزدیک به 160dpi است.

    تبدیل کردن DP به PX

    فرمول تبدیل dp به px به صورت زیر است:

     

    Actual Pixel = dp*(dpi/160)

    که در آن dpi برابر است با 120 یا 160 یا 240 یا 320 است.برای پیدا کردن مقدار پیکسلی viewها از متد ()getWidth و شئ view استفاده کنید:

     

    public void onClick(View view)
    Toast.makeText(this, String.valueOf(view,getWidth()), Toast.LENGTH_LONG).show();

    AbsoluteLayout

    AbsoluteLayout به شما این قابلیت را می دهد تا محل قطعی فرزندش را به صورت دقیق مشخص کنید.فایل main.xml را به صورت زیر ویرایش کنید:

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <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>

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

    TableLayout

    TableLayout می تواند ابزارهای نمایش را در ستون و ردیف دسته بندی کند.از عنصر <TableRow> برای ایجاد یک ردیف در جدول استفاده می کنیم.هر ردیف می تواند یک یا چند view داشته باشد.هر view که در یک ردیف قرار می دهید,به شکل یک سلول در می آید.اندازه ی عرض هر ستون به اندازه ی بزرگترین سلول موجود در آن ستون است.فرض کنید فایل main.xml به صورت زیر است.

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <TableLayout
    xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_height=”fill_parent”
    android:layout_width=”fill_parent”
    >
    <TableRow>
    <TextView
    android:text=”User Name:”
    android:width =”120px”
    />
    <EditText
    android:id=”@+id/txtUserName”
    android:width=”200px” />
    </TableRow>
    <TableRow>
    <TextView
    android:text=”Password:”
    />
    <EditText
    android:id=”@+id/txtPassword”
    android:password=”true”
    />
    </TableRow>
    <TableRow>
    <TextView />
    <CheckBox android:id=”@+id/chkRememberPassword”
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:text=”Remember Password”
    />
    </TableRow>
    <TableRow>
    <Button
    android:id=”@+id/buttonSignIn”
    android:text=”Log In” />
    </TableRow>
    </TableLayout>

    توجه داشته باشید که در مثال فوق,دو ستون و 4 ردیف در TableLayout قرار دارد.سلولی که در زیر TextView پسوورد است به وسیله ی یک عنصر خالی <TextView/> ایجاد شده است.اگر به این شکل عمل نکنید checkBox در زیر TextView قرار میگیرد.

    RelativeLayout

    به شما این قابلیت را می دهد که چینش اجزا, وابسته به چینش یکیدیگر باشند.

    فرض کنید که فایل main.xml به صورت زیر است:

     

    <?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>

    توجه داشته باشید view که در RelativeLayout قرار دارد خصوصیاتی را شامل می شود که به شما اجازه می دهد محل قرارگیری آن را با view دیگری تنظیم کنید.این خصوصیات شامل موارد زیر است:

    • layout_alignParentTop
    • layout_alignParentLeft
    • layout_alignLeft
    • layout_alignRight
    • layout_below
    • layout_centerHorizontal

    مقداری که برای هر کدام از این خصوصیات می توان در نظر گرفت,ID آن view است که می خواهیم به آن اشاره شود.

    FrameLayout

    محلی برای قرار دادن تنها یک view می باشد.viewهایی که به FrameLayout اضافه می شوند,همیشه به سمت چپ و بالای صفحه شما می چسبند.فرض کنید فایل main.xml به صورت زیر باشد.

     

    <?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=”This is my lovely dog, Ookii”
    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/ookii”
    android:layout_width=”wrap_content”
    android:layout_height=”wrap_content”
    />
    </FrameLayout>
    </RelativeLayout>

    در این کدها یک FreamLayout در میان یک RelativeLayout وجود دارد.درون FrameLayout یک ImageView قرار دارد.

    اگر یک view دیگر در FrameLayout اضافه کنید(مثل یک Button) ,بر روی 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=”This is my lovely dog, Ookii”
    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/ookii”
    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 بیافزایید,اما هر کدام از آنها بر روی قبلی قرار می گیرند.با این روش می توانید یک انیمیشن ایجاد کنید و در هر لحظه یکی از view ها را نمایش دهید.

    ScrollView

    یک نوع بخصوصی از FrameLayout است.چون به کاربر اجازه می دهد تا میان لیستی از ابزار های نمایش که تمام فضای فیزیکی صفحه را اشغال کرده اند,پیمایش کند.ScrollView تنها می تواندیک فرزند view یا ViewGroup داشته باشد که معمولاً از LineearLayout استفاده می شود.

    در زیر یک ScrollView را در فایل main.xml نشان داده ایم که حاوی یک LinearLayout است کع آن هم شامل Button و EditText می باشد:

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <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=”300px”
    />
    <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 به صورت خودکار فوکوس دارد,کل اکتیویتی را پر می کند.برای جلوگیری از فوکوس اتوماتیک آن خصوصیات زیر را به <LinearLayout> اضافه کنید:

    focusable

    <LinearLayout
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:orientation=”vertical”
    android:focusable="true"
    android:focusableInTouchMode="true"

    >

     در مواقعی نیاز است تا EditText به صورت خودکار انتخاب شود.اما شما نیازی نمی بینید تا صفحه کلید به صورت خودکار نمایش داده شود.برای جلوگیری از نمایش صفحه کلید خصوصیات زیر را به عنصر <activity> در فایل 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>

    تطبیق با جهت صفحه نمایش

    یکی از ویژگی های کلیدی گوشی های هوشمند,قابلیت چرخش گوشی در جهات افقی و عمودی است.اندروید هم جهت افقی و هم عمودی را پشتیبانی می کند.در حالت عادی وقتی که جهت گوشی را عوض می کنید,اکتیویتی کنونی سعی می کند با توجه به جهت چرخش رابط کاربری را دوباره ترسیم کند.این عمل به این دلیل اتفاق می افتد که در هنگام تغییر جهت گوشی رویداد ()onCreate دوباره فراخوانی می گردد.

    در این حالت تمامی عناصر به جای اصلیشان بر میگردند .دقت کنید که در حالت افقی فضای زیادی در سمت راست بلا استفاده مانده است.علاوه بر آن در حالت افقی ممکن است چند view به دلیل تعدد ابزارهای نمایش و قرار گرفتن در پایین صفحه از نظر پنهان می باشند.معمولاً دو روش برای کنترل تغییر جهت وجود دارد:

    • Anchoring (مهار کردن):بدین معنا که view را به چهار طرف صفحه متصل می کنیم.این راحت ترین راه ممکن است.وقتی که جهت عوض شود,دوباره رابط کاربری شما به چهار طرف متصل می گردد.
    • Resizing and repositioning (تغییر اندازه و چینش دوباره): گرچه روش مهار کردن راحت ترین روش برای اطمینان از نمایش رابط کاربری در جهات مختلف است,اما تکنیک برتر تغییر اندازه تمامی ابزارهای نمایش و چینش دوباره آنها بر اساس جهت کنونی می باشد.

    روش مهار کردن ابزارهای نمایش

    با استفاده از RelativeLayout به راحتی می توان از این روش بهره گرفت.در زیر یک فایل main.xml در اختیار داریم که حاوی پنج دکمه است که درون عنصر <RelativeLayout> قرار دارند:

     

    <?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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    android:layout_centerVertical=”true”
    android:layout_centerHorizontal=”true”
    />
    </RelativeLayout>

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

    • view -- layout_alignParentLeft را در سمت چپ والد می چیند.
    • view -- layout_alignParentRight را در سمت راست والد می چیند.
    • view -- layout_alignParentTop را در بالای والد می چیند.
    • view -- layout_alignParentBottom را در پایین والد می چیند.
    • view -- layout_centerVertical را به صورت عمودی در وسط والد می چیند.
    • view -- layout_centerHorizontal را به صورت افقی در وسط والد می چیند.

    روش تغییر اندازه و چینش مجدد

    به جز روش قبلی یعنی مهار کردن ابزارهای نمایش,یک راه حل راحتتری برای سفارشی سازی رابط کاربری با توجه به جهت چرخش دستگاه,ایجاد فولدرهای مختلف در res/layout و ایجاد فایل های XML به ازای هر کدام از جهات افقی یا عمودی می باشد.برای پشتیبانی حالت افقی,باید یک فولدر در res به نام layout-land ساخته شود.معمولاً فایل main.xml که درون فولدر layout قرار دارد,حاوی رابط کاربری برای حالت عمودی است.اما فایل main.xml که در فولدر layout-land  قرار گرفته است حاوی رابط کاربری برای حالت افقی می باشد.

    کدهای زیر نمایش دهنده ی محتوای فایل 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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    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 Button”
    android:layout_centerVertical=”true”
    android:layout_centerHorizontal=”true”
    android:layout_alignParentBottom=”true”
    />
    </RelativeLayout>

    با استفاده از این روش هرگاه چرخشی به وقوع بپیوندد,اندروید به صورت اتوماتیک XML مربوطه را بارگذاری می کند.

    مدیریت تغییر و چرخش صفحه نمایش

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

    در تمرین زیر رفتار یک اکتیویتی را در هنگام چرخش یک دستگاه را بررسی می کنیم.

    1.یک پروژه ی جدید  با نام  Orientations ایجاد کنید.

    2.فایل main.xml را به صورت زیر تغییر دهید:

     

    <?xml version=”1.0” encoding=”utf-8”?>
    <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
    <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>

    3.فایل MainActivity.java را به صورت زیر تغییر دهید:

     

    package com.PRG.Orientations;
    import android.app.Activity;
    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();
    }
    }

    4.برنامه را اجرا کنید.

    5.با استفاده از کلیدهای Ctrl + F11 جهت شبیه ساز را عوض کنید.

    6.خروجی پنجره ی LogCat را مشاهده کنید.برای این کار باید در ایکلیپس به حالت Bebug prespective بروید.که باید چیزی شبیه زیر باشد:

     

    01-05 13:32:30.266: DEBUG/StateInfo(5477): onCreate
    01-05 13:32:30.296: DEBUG/StateInfo(5477): onStart
    01-05 13:32:30.296: DEBUG/StateInfo(5477): onResume
    ...
    01-05 13:35:20.106: DEBUG/StateInfo(5477): onPause
    01-05 13:35:20.106: DEBUG/StateInfo(5477): onStop
    01-05 13:35:20.106: DEBUG/StateInfo(5477): onDestroy
    01-05 13:35:20.246: DEBUG/StateInfo(5477): onCreate
    01-05 13:35:20.256: DEBUG/StateInfo(5477): onStart
    01-05 13:35:20.256: DEBUG/StateInfo(5477): onResume

    روش کار

    از نوشته های این پنجره ی LogCat می توان به این نتیجه رسید که در هنگام چرخش دستگاه,اکتیویتی نابود می شود:


    01-05 13:35:20.106: DEBUG/StateInfo(5477): onPause
    01-05 13:35:20.106: DEBUG/StateInfo(5477): onStop
    01-05 13:35:20.106: DEBUG/StateInfo(5477): onDestroyااا

    و در ایجاد دوباره ی آن به صورت زیر می شود:

     

    01-05 13:35:20.246: DEBUG/StateInfo(5477): onCreate
    01-05 13:35:20.256: DEBUG/StateInfo(5477): onStart
    01-05 13:35:20.256: DEBUG/StateInfo(5477): onResume

    درک این رفتار اندروید بسیار مهم است.چون شما باید این موضوع را به خوبی بدانید تا بتوانید وضعیت اکتیویتی را قبل از چرخش دستگاه حفظ کنید.به عنوان مثال فرض کنید که اکتیویتی شما دارای مقادیری است که برای انجام محاسبات به آن احتیاج دارید.برای حفظ وضعیت اکتیویتی باید در هنگام رویداد ()onPause هر کاری را که لازم است انجام دهید.چرا که در هنگام چرخش اولین رویدادی که رخ می دهد این رویداد است.نکته ی قابل توجه دیگر این است که تنها ابزارهای نمایشی که در خصوصیت android:id آنها نام گذاری صورت گرفته است,بعد از چرخش وضعیت قبلی خود را حفظ خواهند کرد.فرض کنید کاربر در حال وارد کردن متنی در یک EditText است, ناگهان یک چرخش صورت می گیرد.به محض اینکه این رویداد رخ دهد , آن EditText به صورت اتوماتیک در هنگام دوباره ایجاد شدن اکتیویتی,حاوی متنی است که تا کنون وارد شده و کاربر به راحتی به کار خود ادامه می دهد.اما اگر نام گذاری به واسطه ی android:id صورت نگیرد, اکتیویتی نمی تواند محتوای کنونی را به حالت قبل از چرخش باز گرداند.

    تداوم وضعیت اطلاعات هنگام تغییرات اساسی

    تا اینجای کار متوجه شدید که در هنگام چرخش دستگاه,اکتیویتی نابود شده و دوباره ایجاد می شود.این نکته را نیز می دانید که ایجاد دوباره رابط کاربری تضمینی برای حفظ حالت قبلی خود ندارد.وقتی یک اکتیویتی نابود می شود حداقل یکی از متدهای زیر اجرا می شود:

    • ()onPause -- این متد همیشه هنگامی که اکتیویتی نابود می گردد و یا به پس زمینه می رود,اجرا می گردد.
    • ()onSaveInstanceState -- این متد هم مثل متد بالایی در هنگام نابودی اکتیویتی و یا در هنگام رفتن اکتیویتی به پس زمینه اجرا می گردد.اما بر  خلاف متد ()onPause این متد در هنگام تخلیه ی اکتیویتی از stack, اجرا نمی گردد.مثل زمانی که کاربر کلید Back دستگاه را فشار می دهد.چون نیازی به بازیابی وضعیت نمی باشد.

    به طور کلی برای حفظ وضعیت اکتیویتی,همیشه باید متد ()onPause را پیاده سازی کرد,و بعد نسبت به بازیابی آن از روش هایی مثل استفاده از بانک اطلاعاتی, ذخیره در حافظه درونی یا بیرونی و... استفاده کرد.

    اگر راه آسان حفظ اطلاعات مطلوب شماست و تنها می خواهید هنگامی که اکتیویتی مجدداً ایجاد شد,اطلاعات حفظ شده بازیابی گردد.مثل زمانی که گوشی چرخش دارد.بهترین کار پیاده سازی متد ()onSaveInstanceState است.این متد یک شئ Bundle را به عنوان آرگومان ارائه می دهد که به وسیله ی آن می توانید وضعیت اکتیویتی را حفظ کنید.مثال زیر نحوه ی ذخیره یک رشته به نام ID را درون شئ Bundle در متد()onsaveInstanceState نشان می دهد:

     

    @Override
    public void onSaveInstanceState(Bundle outState) {
    //---save whatever you need to persist---
    outState.putString(“ID”, “1234567890”);
    super.onSaveInstanceState(outState);
    }

    وقتی که یک اکتیویتی دوباره ایجاد شد,اولین متدی که اجرا می شود متد ()onCreate است, به دنبال آن متد ()onRestoreInstanceState نیز اجرا می گردد که باعث می شود تا حالت قبلی که با استفاده از متد ()onSaveInstanceState که به واسطه ی شئ Bundle به عنوان آرگومان ذخیره شده است,بازیابی گردد:

     

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    //---retrieve the information persisted earlier---
    String ID = savedInstanceState.getString(“ID”);
    }

     این در حالی است که از متد ()onSaveInstanceState نیز برای حفظ اطلاعات استفاده می کنید.توجه داشته باشید که تنها میتوان اطلاعات را در شئ Bundle ذخیره نمود.اگر به دنبال ذخیره ی اطلاعات بیشتر و پیچیده تری هستید,این روش راه حل مناسبی نیست.راه دیگری که می توان از آن استفاده کرد,بکار بردن متد()onRetainNonConfigurationInstance است.این متد هم هنگامی اجرا می شود که اکتیویتی به دلیل رویدادها و تغییرات اساسی در حال نابودی باشد مثل وقتی که جهت دستگاه عوض شود می توان با برگشت داده از طریق این متد,داده مورد نظر را حفظ کرد.مثل کد زیر:

     

    @Override
    public Object onRetainNonConfigurationInstance() {
    //---save whatever you want here; it takes in an Object type---
    return(“Some text to preserve”);
    }

     وقتی جهت تصویر تغییر می کند ,این تغییر را یک تغییر اساسی می نامند.تغییرات اساسی باعث می شوند که اکتیویتی نابود گردد.توجه داشته باشید که  خروجی این متد از نوع Object است که به شما این اجازه را می دهد از هر نوع داده ی مورد نظر استفاده کنید.برای استخراج اطلاعات ذخیره شده میتوانید در متد ()onCreate این کار را با استفاده از متد ()getLastNonConfigurationInstance انجام دهید:

     

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Log.d(“StateInfo”, “onCreate”);
    String str = (String) getLastNonConfigurationInstance();
    }

    یکی از استفاده های بجا از متدهای ()onRetainNonConfigurationInstance و ()getLastNonConfigurationInstnce زمانی است که می خواهید اطلاعاتی را به صورت لحظه ای حفظ کنید.مثل زمانی که در حال دانلود اطلاعات از یک وب سرویس هستید و در همان لحظه یک چرخش ایجاد می گردد.در این حالت استفاده از متدهای بالا بسیار کاربردی و با کارایی بیشتر به نظر می رسد.

    تشخیص تغییر جهت

    در بعضی مواقع نیاز است تا در زمان اجرا برنامه وضعیت جهت دستگاه را بدانیم.برای این کار از کلاس WindowManager استفاده می کنیم.در کد زیر نشان می دهیم که چگونه وضعیت دستگاه را در زمان اجرا تشخیص دهیم:

     

    import android.util.Log;
    import android.view.Display;
    import android.view.WindowManager;
    //...
    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 که همان صفحه نمایش دستگاه است را باز می گرداند.سپس می توانید طول و عرض آن را گرفته و به وسیله ی آنها جهت دستگاه را پیدا کنید.

    کنترل جهت یک اکتیویتی

     گاهی اوقات ممکن است تمایل داشته باشید که اکتیویتی شما فقط در یک جهت نمایش داده شود.برای مثال یک بازی معمولاً در حالت افقی نمایش داده می شود.برای این کار می توانید از متد ()setRequestOrientation کلاس Activity استفاده کنید:

     

    import android.content.pm.ActivityInfo;
    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);
    //---change to landscape mode---
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    برای نمایش در حالت عمودی از ثابت ActivityInfo.SCREEN_ORIENTATION_PORTRAT استفاده کنید.

     

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    به غیر از متد ()setRequestOrientation می توانید از خصوصیت android:screenOrientation عنصر<activity> در فایل AndroidManifest نیز مانند مثال زیر برای تعیید جهت صفحه نمایش استفاده کنید:


    <?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”>
    <application android:icon=”@drawable/icon” android:label=”@string/app_name”>
    <activity android:name=”.MainActivity”
    android:label=”@string/app_name”
    android:screenOrientation=”landscape” >
    <intent-filter>
    <action android:name=”android.intent.action.MAIN” />
    <category android:name=”android.intent.category.LAUNCHER” />
    </intent-filter>
    </activity>
    </application>
    <uses-sdk android:minSdkVersion=”9” />
    </manifest>

    کد بالا اکتیویتی را در یک جهت مشخص نمایش می دهد که در اینجا به صورت افقی است,و از نابود شدن اکتیویتی جلوگیری میکند.این به این معنا است که اکتیویتی با چرخش دستگاه نابود نشده و متد ()onCreate دوباره فراخوانی نمی گردد.در زیر دو مقدار دیگر که می توانید از آنها در خصوصیت android:screenOrientation استفاده کنید را مشاهده می کنید:

    • portrait --حالت عمودی
    • Sensor --بر اساس سنسور شتاب سنج(پیش فرض)
    READ MORE
  • آن چه در این آموزش فرا می گیرید:

    1. تعریف یک واسط
    2. پیاده سازی کردن Interface
    3. تحویل یک پیغام به Fragment

    مواردی که باید مطالعه کرده باشید:

    • Fragmentها

    خودتان امتحان کنید:

    دانلود دمو »

    ارتباط با سایر framentها

    به منظور استفاده ی مجدد از کامپوننت های واسط گرافیکی fragment، می بایست هر یک از کامپوننت ها را به صورت مولفه های ماژولار مستقل ایجاد کرد. این مولفه ها، چیدمان و رفتار تعریف شده ی مخصوص به خود را دارا هستند. هنگامی که fragmentهای قابل استفاده را تعریف کردید، می توان آن ها را با یک activity مرتبط کرد و آن ها را با منطق برنامه متصل کرد و یک واسط گرافیکی ترکیبی را ایجاد کرد.

    برخی اوقات می خواهید یک fragment با دیگری ارتباط داشته باشد، مثلاً می خواهید محتوا را بر اساس رویداد کاربر تغییر دهید. همه ی ارتباط های بین دو fragment از طریق Activity مرتبط امکان پذیر است. دو fragment نباید مستقیماً ارتباط برقرار کنند.


    تعریف یک واسط

    برای اینکه اجازه بدهیم یک fragment با activity بالاسریش ارتباط برقرار کند، می توان یک interface در کلاس Fragment تعریف کرد و آن را در کلاس Activity پیاده سازی کرد. Fragment پیاده سازی interface را با استفاده از متد ()onAttach چرخه ی حیات دریافت می کند و سپس می تواند متدهای interface را برای ارتباط با Activity فراخوانی کند.

    در زیر یک مثال برای ارتباطا بین activity و fragment آورده شده است:


    public class HeadlinesFragmentextendsListFragment{
    OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    publicinterfaceOnHeadlineSelectedListener{
    publicvoid onArticleSelected(int position);
    }

    @Override
    public void onAttach(Activity activity){
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try{
    mCallback =(OnHeadlineSelectedListener) activity;
    }catch(ClassCastException e){
    thrownewClassCastException(activity.toString()
    +" must implement OnHeadlineSelectedListener");
    }
    }

    ...
    }

    حالا fragment می تواند پیغام هایی را به activity با فراخوانی متد ()onArticleSelected (یا سایر متدهای واسط) تحویل دهد. این کار با استفاده از نمونه ی mCallBack مربوط به واسط onHeadlineSelectedListener انجام داد.

    برای مثال، وقتی کاربر روی یکی از آیتم های لیست کلیک می کند، متد زیر در fragment صدا زده می شود. fragment از Intrface برای تحویل رویداد به activity والد استفاده می کند.

    Title

     
    @Override
    public void onListItemClick(ListView l,View v,int position,long id){
    // Send the event to the host activity
    mCallback.onArticleSelected(position);
    }
     

    پیاده سازی کردن Interface

    یک activity، برای دریافت رویدادهای یک fragment، می بایست interfaceی که داخل کلاس fragment تعریف شده است را پیاده سازی کند.

    برای مثال، Activity زیر interface مثال بالا را پیاده سازی می کند:

    پیاده سازی interface

     
    public static class MainActivity extends Activity
    implementsHeadlinesFragment.OnHeadlineSelectedListener{
    ...

    publicvoid onArticleSelected(int position){
    // The user selected the headline of an article from the HeadlinesFragment
    // Do something here to display that article
    }
    }


    تحویل یک پیغام به Fragment

    activity میزبان می تواند پیغام ها را به fragment تحویل دهد. برای این کار باید با استفاده از ()findFragmentById، نمونه ی Fragment را بدست بیاورد، سپس مستقیماً متدهای عمومی fragment را فراخوانی می کند.

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

    تحویل اطلاعات از Activity به fragment دیگر

     
    public static class MainActivity extends Activity
    implementsHeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position){
    // The user selected the headline of an article from the HeadlinesFragment
    // Do something here to display that article

    ArticleFragment articleFrag =(ArticleFragment)
    getSupportFragmentManager().findFragmentById(R.id.article_fragment);

    if(articleFrag !=null){
    // If article frag is available, we're in two-pane layout...

    // Call a method in the ArticleFragment to update its content
    articleFrag.updateArticleView(position);
    }else{
    // Otherwise, we're in the one-pane layout and must swap frags...

    // Create fragment and give it an argument for the selected article
    ArticleFragment newFragment =newArticleFragment();
    Bundle args =newBundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment.setArguments(args);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);

    // Commit the transaction
    transaction.commit();
    }
    }
    }
    READ MORE
  • آن چه در این آموزش فرا می گیرید:

    1. افزودن fragment در زمان اجرا
    2. جایگزین کردن یک fragment با دیگری

    مواردی که باید مطالعه کرده باشید:

    • Fragmentها

    خودتان امتحان کنید:

    دانلود دمو »

    ایجاد یک UI انعطاف پذیر

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

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

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

    کلاس FragmetnManager به شما اجازه می دهد که زمان اجرا fragmentها را به یک activity اضافه کنید، یا از آن حذف کنید و یا با همدیگر جایگزین کنید. با این کار fragmentها پویا می شوند.


    آموزش اندروید - افزودن یک fragment به Activity در زمان اجرا

    در آموزش اندروید بیاموز قبل دیدیم که در فایل چیدمان می توانیم fragmentها را با استفاده از عنصر <fragment> تعریف کرد. حال به جای تعریف fragment در فایل اجرا می خواهیم یک fragment را در زمان اجرا به یک Activity اضافه کنیم. این کار هنگامیکه شما قصد دارید fragmentها را در زمان حیات activity تغییر بدهید، ضروری است.

    برای انجام عملیاتی مانند افزودن یا حذف یک fragment، می بایست از FragmentManager برای ایجاد FragmentTransaction استفاده کرد، این کلاس APIهایی برای افزودن، حذف یا جایگزینی و اجرای دیگر عملیات fragment فراهم می کند.

    اگر activity شما اجازه دهد که fragmentها حذف یا اضافه شوند، شما می بایست fragment (های) اولیه را در متد ()onCreate به activity اضافه کنید.

    یک قانون مهم در برخورد با fragmentها -خصوصاً آن هایی که زمان اجرا به activity اضافه می شوند- عبارت است از اینکه fragment می بایست دارای یک view کانتینر در چیدمان باشد و fragment درون آن قرار می گیرد.

    چیدمان زیر را می توان به جای چیدمانی که در آموزش اندروید درس قبلی اشاره کردیم به کار ببریم. در آن چیدمان تنها یک fragment در زمان اجرا نمایش داده می شد. برای اینکه fragmentها با یکدیگر جایگزین شوند، چیدمان activity دارای یک FrameLayout خالی است که به عنوان fragment کانتینر عمل می کند.

    توجه نمایید که نام فایل مشابه فایل چیدمان در آموزش اندروید بیاموز قبلی می باشد، اما دایرکتوری چیدمان پسوند large را ندارد، بنابراین این چیدمان هنگامی که صفحه نمایش دستگاه بزرگ نیست استفاده می شود، زیرا دو fragment در یک صفحه نمایش هم زمان جا نمی شود.

    فایل چیدمان

    res/layout/news_articles.xml:

    <FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

    داخل activity متد ()getSupportFragmentManager را فراخوانی کنید تا بتوانیم از FragmentManager کتابخانه ی پشتیبان استفاده کنیم. بعد از آن ()beginTransaction را برای ایجاد یک FragmentTransaction صدا بزنید و سپس متد ()add، یک fragment را اضافه می کند.

    شما می بایست چندین عملیات fragment را با استفاده از FragmentTransaction روی activity اجرا کنید. هنگامی که شما آماده ی تغییرات هستید، می بایست متد ()commit را اجرا نمایید.

    در مثال زیر، نجوه ی افزودن fragment به چیدمان بالا آورده شده است:

    افزودن fragment به چیدمان در زمان اجرا

     
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;

    public class MainActivity extends FragmentActivity{
    @Override
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.news_articles);

    // Check that the activity is using the layout version with
    // the fragment_container FrameLayout
    if(findViewById(R.id.fragment_container)!=null){

    // However, if we're being restored from a previous state,
    // then we don't need to do anything and should return or else
    // we could end up with overlapping fragments.
    if(savedInstanceState !=null){
    return;
    }

    // Create a new Fragment to be placed in the activity layout
    HeadlinesFragment firstFragment =new HeadlinesFragment();

    // In case this activity was started with special instructions from an
    // Intent, pass the Intent's extras to the fragment as arguments
    firstFragment.setArguments(getIntent().getExtras());

    // Add the fragment to the 'fragment_container' FrameLayout
    getSupportFragmentManager().beginTransaction()
    .add(R.id.fragment_container, firstFragment).commit();
    }
    }
    }

    به این دلیل که fragment در زمان اجرا به کانتینر FrameLayout اضافه شده است، activity می تواند fragment را حذف کند یا با سایر fragmentها جا به جا کنید.


    آموزش اندروید - جایگزین کردن یک fragment با دیگری در زمان اجرا

    فرایند جایگزین کردن fragment مشابه افزودن آن است، با این تفاوت که به جای متد ()add می بایست از متد ()replace استفاده کنیم.

    به خاطر داشته باشید، وقتی که یک عملیات fragment انجام می دهید، مانند جایگزینی یا حذف fragment، معمولاً باید به کاربر اجازه بدهیم تا تغییرات را برگرداند و به اصطلاح تغییرات را undo کند. برای اینکه به کاربر اجازه دهیم تا در عملیات fragment به عقب برگردد، می بایست متد ()addToBackStack را قبل از اجرای FragmentTransaction فراخوانی کنیم.

    Note

    توجه: هنگامی که یک fragment را حذف می کنیم یا جایگزین می کنیم و عملیات را به پشته اضافه می کنیم، fragmentی که حذف شده است متوقف می شود (و از بین نمی رود). اگر کاربر به عقب برگردد تا fragment را بازیابی کند، fragment مجدداً شروع می شود. اگر عملیات را به پشته اضافه نکنید، fragment هنگامی که حذف یا جایگزین می شود از بین می رود.

    مثال زیر جایگزینی یک fragment با سایر fragmentهاست:

    جایگزین کردن یک fragment با دیگری


    // Create fragment and give it an argument specifying the article it should show
    ArticleFragment newFragment =new ArticleFragment();
    Bundle args =new Bundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment.setArguments(args);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack so the user can navigate back
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);

    // Commit the transaction
    transaction.commit();

    متد ()addToBackStack دارای یک پارامتر رشته ای اختیاری است که نام منحصر به فردی را برای عملیات مشخص می کند. این پارامتر یعنی نام نیاز نمی باشد مگر اینکه قصد دارید عملیات پشرفته ای را با استفاده از FragmentManager انجام دهید.

    // ![DATA[ try{ loc=location.pathname; //if (loc.toUpperCase().indexOf(".ASP")0) loc=loc+"default.asp"; txt='<a href="http://www.facebook.com/sharer.pp?u=http://www.beyamooz.com'+loc+'" target="_blank" title="Facebook">' txt=txt+''; txt=txt+''; txt=txt+''; //txt=txt+''; //txt=txt+'';
    // ]]>
    READ MORE
تمامی محصولات و خدمات این وبسایت، حسب مورد دارای مجوزهای لازم از مراجع مربوطه می‌باشند و فعالیت‌های این سایت تابع قوانین و مقررات جمهوری اسلامی ایران است.
logo-samandehi مجوز نشر دیجیتال از وزرات فرهنگ و ارشاد اسلامی پرداخت آنلاین -  بانک ملت معرفی بیاموز در شبکه سه