سبد (0)

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

  • پیش نیازها

    • Android 1.6 یا بالاتر

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

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

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

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


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

    READ MORE
  • آن چه در این آموزش فرا می گیرید:

    1. فایل منیفست را به روز رسانی کنید
    2. مدیریت محتوای ورودی

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

    • Intentها و فیلترها

    آموزش اندروید - دریافت داده از دیگر Appها

     

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


    فایل منیفست خود را به روز رسانی کنید

    فیلترهای Intent به سیستم اطلاع رسانی می کنند که یک برنامه چه intentهایی را دریافت می کند. دقیقاً مانند حالتی که شما یک intent را با actionی با نام ACTION_SEND ایجاد کردید (به آموزش آموزش اندروید-ارسال به دیگر appها مراجعه نمایید)، می توانید برای اینکه برنامه بتواند intentهای این action را دریافت کند فیلترهایی را ایجاد کنید. با استفاده از یک فیلتر intent در فایل منیفست ایجاد نمایید. برای مثال اگر برنامه ی شمامحتوای متنی و یک عکس از نوع خاص و چند عکس با هر نوعی را دریافت می کند، فایل منیفست به صورت زیر خواهد بود:

     

     

     
    activityandroid:name=".ui.MyActivity">
       
    <intent-filter>
           
    <actionandroid:name="android.intent.action.SEND"/>
           
    <categoryandroid:name="android.intent.category.DEFAULT"/>
           
    <dataandroid:mimeType="image/*"/>
       
    </intent-filter>
       
    <intent-filter>
           
    <actionandroid:name="android.intent.action.SEND"/>
           
    <categoryandroid:name="android.intent.category.DEFAULT"/>
           
    <dataandroid:mimeType="text/plain"/>
       
    </intent-filter>
       
    <intent-filter>
           
    <actionandroid:name="android.intent.action.SEND_MULTIPLE"/>
           
    <categoryandroid:name="android.intent.category.DEFAULT"/>
           
    <dataandroid:mimeType="image/*"/>
       
    </intent-filter>
    </activity>

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


    مدیریت محتوای ورودی

    برای اینکه محتوایی که intent ارسال می کند را مدیریت کنید، با متد ()getIntent شروع کنید و شیء Intent را دریافت کنید. بعد از دریافت شیء Intent، می توانید محتوای آن را بررسی کنید تا کاری که باید بعد از آن انجام دهید، مشخص شود. به خاطر داشته باشید که اگر Activity که intent را دریافت می کند می بایست از طریق سایر قسمت های سیستم مانند launcher یا آغازگر، راه اندازی شود، این موضوع حتماً می بایست در زمان بررسی Intent لحاظ شود.

     

     
    void onCreate(Bundle savedInstanceState){
       
    ...
       
    // Get intent, action and MIME type
       
    Intent intent= getIntent();
       
    String action= intent.getAction();
       
    String type= intent.getType();

       
    if(Intent.ACTION_SEND.equals(action)&& type!=null){
           
    if("text/plain".equals(type)){
                handleSendText
    (intent);// Handle text being sent
           
    }elseif(type.startsWith("image/")){
                handleSendImage
    (intent);// Handle single image being sent
           
    }
       
    }elseif(Intent.ACTION_SEND_MULTIPLE.equals(action)&& type!=null){
           
    if(type.startsWith("image/")){
                handleSendMultipleImages
    (intent);// Handle multiple images being sent
           
    }
       
    }else{
           
    // Handle other intents, such as being started from the home screen
       
    }
       
    ...
    }

    void handleSendText(Intent intent){
       
    String sharedText= intent.getStringExtra(Intent.EXTRA_TEXT);
       
    if(sharedText!=null){
           
    // Update UI to reflect text being shared
       
    }
    }

    void handleSendImage(Intent intent){
       
    Uri imageUri=(Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
       
    if(imageUri!=null){
           
    // Update UI to reflect image being shared
       
    }
    }

    void handleSendMultipleImages(Intent intent){
       
    ArrayList<Uri> imageUris= intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
       
    if(imageUris!=null){
           
    // Update UI to reflect multiple images being shared
       
    }
    }

    Note

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

    READ MORE
  • آموزش اندروید کنترل صدا و پخش رسانه در برنامه

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

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

     


     تعیین اینکه از چه جریان صوتی استفاده کنیم

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

    اندروید از یک جریان صوتی مجزا برای پخش موسیقی، هشدار، پیغام، زنگ تماس، صداهای صوتی و تن های DTMF استفاده می کند. این کار اساساً به این خاطر است که کاربر بتواند میزان صدای هر کدام از جریان ها را به صورت مستقل کنترل کند.

    اکثر این جریان ها محدودیت هایی را در مقابل رویدادهای سیستمی دارند، بنابراین به غیر از مواردی که برنامه ی شما هشدار ساعت می باشد، تقریباً در اکثر اوقات شما از جریان STREAM_MUSIC برای پخش صوت استفاده می کنید.

    استفاده از کلید سخت افزاری کنترل صدا برای کنترل میزان صدای برنامه


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

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

    شاید شما بخواهید میزان صدای برنامه را با فشردن دکمه ی میزان صدا تغییر دهید. اندروید متد ()setVolumeControlStream را در اختیار شما گذاشته تا شما بتوانید جریان صوتی که مد نظرتان هست را هنگام فشردن دکمه ی میزان صوت کنترل کنید.

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

    setVolumeControlStream(AudioManager.STREAM_MUSIC);

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

    استفاده از کلیدهای کنترل پخش سخت افزاری برای پخش صوت برنامه


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

    وقتی کاربری یکی از این دکمه های سخت افزاری را کلیک می کند، سیستم یک intent با اقدام ACTION_MEDIA_BUTTON منتشر می کند.

    برای پاسخ به رویداد کلیک، می بایست یک BroadcastReceiver در منیفست برنامه ثبت کنیم که به این انتشار پاسخ دهد. مانند تکه کد زیر:

    پاسخ به BroadcastReceiver

    <receiverandroid:name=".RemoteControlReceiver">
       
    <intent-filter>
           
    <actionandroid:name="android.intent.action.MEDIA_BUTTON"/>
       
    </intent-filter>
    </receiver>

    حال در پیاده سازی نیاز است که مشخص کنیم چه کلیدی فشرده شده است. Intent این کلید ها را در EXTRA_KEY_EVENT دارد. کلاس KeyEvent حاوی لیستی از *_KEYCODE_MEDIA است که هر یک از دکمه ها را نشان می دهد، مثلاً KEY_CODE_MEDIA_PLAY_PAUSE و KEYCODE_MEDIA_NEXT می باشد.

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

    پاسخ به رویداد کلیک

    publicclassRemoteControlReceiverextendsBroadcastReceiver{
       
    @Override
       
    publicvoid onReceive(Context context,Intent intent){
           
    if(Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())){
               
    KeyEventevent=(KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
               
    if(KeyEvent.KEYCODE_MEDIA_PLAY==event.getKeyCode()){
                   
    // Handle key press.
               
    }
           
    }
       
    }
    }
     

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

    می توانید از تکه کد زیر در برنامه ی خود استفاده کنید. در این کد می توانید با ثبت رویداد دکمه ی مدیا به آن پاسخ دهید و یا اینکه می توانید از آن صرف نظر کنید.

     

    AudioManager am= mContext.getSystemService(Context.AUDIO_SERVICE);
    ...

    // Start listening for button presses
    am
    .registerMediaButtonEventReceiver(RemoteControlReceiver);
    ...

    // Stop listening for button presses
    am
    .unregisterMediaButtonEventReceiver(RemoteControlReceiver);

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

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

    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. استفاده از تم اندروید
    2. سفارشی سازی پس زمینه
    3. مشخص کردن رنگ متن
    4. سفارشی کردن سربرگ ها

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

    • استایل ها و تم ها
    • تولید استایل action bar اندروید

    action bar برای کاربران روش ساده تری را برای اجرای actionها و چرخ زدن در برنامه فراهم می کند، اما این بدان معنا نیست که ظاهر آن باید دقیقاً مانند سایر برنامه ها باشد. اگر بخواهید ظاهر action bar را تغییر دهید جوری که متناسب با نام تجاری شما شود، می توانید خیلی ساده و از طریق منابع Style و Theme اندروید این کار را انجام دهید.

    اندروید حاوی تعدادی تم activity داخلی است که شامل استایل های "تاریک" یا "روشن" می باشد. می توانید این تم ها را توسعه دهید و هر جور که می خواهید آن ها را برای action bar خود سفارشی کنید.

    توجه: اگر از کتابخانه ی پشتیبان برای action bar استفاده می کنید، می بایست استایلی از خانواده ی Theme.AppCompact استفاده کنید ( به جای استفاده از Theme.Holo). با استفاده از این کار، هر یک از خصوصیت های استایل در کتابخانه پشتیبان قرار دارد.


     استفاده از تم اندروید

    اندروید دارای دو تم مبنا است که رنگ action bar را نشان می دهد:

    • Theme.Holo برای ظاهر و تم "تاریک"
    • Theme.Holo.Light برای ظاهر و تم "روشن".

    می توانید این تم ها را در کل برنامه به کار بگیرید یا اینکه برای Activityهای خاصی از آن برنامه از این تم ها استفاده کنید. برای این کار می توانید از خصوصیت android:theme در عنصر <application> برای بکارگیری در کل برنامه یا به ازای هر activity و داخل عنصر <activity> استفاده کنید.

    مثال:

    مثال بکارگیری تم

     
    <application android:theme="@android:style/Theme.Holo.Light"... />

    شما همچنین می توانید از یک Action bar تاریک برای یک Action خاص استفاده کنید در صورتی که سایر activityها از رنگ روشن بهره می برد. برای این کار باید تم Theme.Holo.Light.DarkActionBar استفاده کنید.

    هنگام استفاده از کتابخانه ی پشتیبان، می بایست از Them.AppCompact استفاده کنید

    • Theme.AppCompact برای ظاهر و تم "تاریک"
    • Theme.AppCompact.Light برای ظاهر و تم "روشن".

    مطمئن باشید که از آیکن های action barی که با رنگ action bar شما متناسب است، استفاده کنید. باید اشاره کنیم که Action Bar Icon Pack حاوی آیکن هایی است که می توانید هم برای تم Holo تاریک و هم تم Holo روشن استفاده کنید.


    سفارشی سازی پس زمینه

     برای تغییر رنگ پس زمینه، یک تم سفارشی برای activity خود ایجاد کنید. خصوصیت actionBarStyle را override کنید. این خصوصیت به استایل دیگری اشاره می کند که در آن می توانید خصوصیت background را override کنید تا منابع قابل ترسیمی را برای پس زمینه action bar مشخص کنیم.

    اگر در برنامه ی خود از از سربرگ ها (tabها) یا از split action bar ها استفاده کردید، آنگاه می توانید پس زمینه را به ترتیب با استفاده از خصوصیت های backgroundStacked و backgroundSplit مشخص کنید.

    Note

    هشدار: تعریف کردن یک تم والد مناسب که تم سفارشی شما از استایل های  آن ارث بری می کند فوق العاده حائز اهمیت است. بدون استایل والد، action bar شما اکثر خصوصیت های مربوط به استایل و ظاهر را ندارد مگر این که خود شما به صورت صریح آن ها را تعریف کرده باشید.


    برای اندرویدهای 3.0 و بالاتر

    وقتی که از اندروید 3.0 یا بالاتر استفاده می کنید، می توانید پس زمینه action bar را به صورت زیر تعریف نمایید:

    در فایل res/values/themes.xml

    Title


    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@android:style/Theme.Holo.Light.DarkActionBar">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
        </style>
    
        <!-- ActionBar styles -->
        <style name="MyActionBar"
               parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
            <item name="android:background">@drawable/actionbar_background</item>
        </style>
    </resources>
    

    حالا می توانید این تم را به کل برنامه یا تک تک activityها اعمال کنید:

    اعمال تم به کل Activityها


    <application android:theme="@style/CustomActionBarTheme"... />


     برای اندرویدهای 2.1 و بالاتر

    هنگام استفاده از کتابخانه ی پشتیبان، تم مشابه آنچه در بالا تعریف کردیم را بایستی به صورت زیر باید تعریف کنیم:

    در فایل res/values/theme.xml


    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat.Light.DarkActionBar">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
    
            <!-- Support library compatibility -->
            <item name="actionBarStyle">@style/MyActionBar</item>
        </style>
    
        <!-- ActionBar styles -->
        <style name="MyActionBar"
               parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
            <item name="android:background">@drawable/actionbar_background</item>
    
            <!-- Support library compatibility -->
            <item name="background">@drawable/actionbar_background</item>
        </style>
    </resources>
    

     

    حالا می توانید این تم را به کل برنامه یا تک تک activityها اعمال کنید:


     
    <application android:theme="@style/CustomActionBarTheme"... />


    مشخص کردن رنگ متن

    برای تغییر رنگ متن در action bar، می بایست چندین خصوصیت مربوط به هر عنصر متنی را بازنویسی کنید:

    • action bar title: یک استایل سفارشی ایجاد می کند که خصوصیت textColor را مشخص می کند. این خصوصیت همچنین استایل مربوط به خصوصیت titleTextStyle را در actionBarStyle مشخص می کند.
      Note

      توجه: استایل سفارشی که روی titleTextStyle اعمال می شود می بایست از TextAppearance.Holo.Widget.ActionBar.Title به عنوان استایل والد استفاده کند.

    • سربرگ های action bar: در تم activity خود actionBarTabTextStyle را بازنویسی کنید.
    • دکمه ها: در تم Activity خود actionMenuTextColor را بازنویسی کنید.

     برای اندرویدهای 3.0 و بالاتر

    هنگام استفاده از اندرویدهای 3.0 یا بالاتر، فایل استایل دهی XML به صورت زیر می باشد:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.Holo">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="android:actionMenuTextColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar styles -->
        <style name="MyActionBar"
               parent="@style/Widget.Holo.ActionBar">
            <item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
        </style>
    
        <!-- ActionBar title text -->
        <style name="MyActionBarTitleText"
               parent="@style/TextAppearance.Holo.Widget.ActionBar.Title">
            <item name="android:textColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar tabs text styles -->
        <style name="MyActionBarTabText"
               parent="@style/Widget.Holo.ActionBar.TabText">
            <item name="android:textColor">@color/actionbar_text</item>
        </style>
    </resources>

     برای اندروید های 2.1 به بعد

    وقتی از اندرویدهای 2.1 به بعد استفاده می کنید، فایل استایل دهی XML به صورت زیر می باشد:

    res/values/themes.xml

     
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="android:actionMenuTextColor">@color/actionbar_text</item>
    
            <!-- Support library compatibility -->
            <item name="actionBarStyle">@style/MyActionBar</item>
            <item name="actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="actionMenuTextColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar styles -->
        <style name="MyActionBar"
               parent="@style/Widget.AppCompat.ActionBar">
            <item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
    
            <!-- Support library compatibility -->
            <item name="titleTextStyle">@style/MyActionBarTitleText</item>
        </style>
    
        <!-- ActionBar title text -->
        <style name="MyActionBarTitleText"
               parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
            <item name="android:textColor">@color/actionbar_text</item>
            <!-- The textColor property is backward compatible with the Support Library -->
        </style>
    
        <!-- ActionBar tabs text -->
        <style name="MyActionBarTabText"
               parent="@style/Widget.AppCompat.ActionBar.TabText">
            <item name="android:textColor">@color/actionbar_text</item>
            <!-- The textColor property is backward compatible with the Support Library -->
        </style>
    </resources>

    سفارشی کردن سربرگ ها

    برای تغییر ظاهر سربرگ ها، یک تم ایجاد کنید که خصوصیت actionBarTabStyle را بازنویسی می کند. این خصوصیت به منبع استایل دیگری اشاره می کند که خصوصیت background را لغو کرده است و آن را به صورت لیست وضعیت قابل ترسیم مشخص می کند.

    مچنین استایل مربوط به خصوصیت titleTextStyle را در actionBarStyle مشخص می کند.

    Note

    توجه:یک لیست وضعیت قابل ترسیم حائز اهمیت است به نحوی که سربرگی که الان انتخاب شده است، وضعیتش را با پس زمینه متفاوتی نسبت به سایر سربرگ ها نشان می دهد. در رابطه با لیست وضعیت یا state list در آینده بیشتر توضیح خواهیم داد.

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

     res/drawable/actionbar_tab_indicator.xml

     
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- STATES WHEN BUTTON IS NOT PRESSED -->
    
        <!-- Non focused states -->
        <item android:state_focused="false" android:state_selected="false"
              android:state_pressed="false"
              android:drawable="@drawable/tab_unselected" />
        <item android:state_focused="false" android:state_selected="true"
              android:state_pressed="false"
              android:drawable="@drawable/tab_selected" />
    
        <!-- Focused states (such as when focused with a d-pad or mouse hover) -->
        <item android:state_focused="true" android:state_selected="false"
              android:state_pressed="false"
              android:drawable="@drawable/tab_unselected_focused" />
        <item android:state_focused="true" android:state_selected="true"
              android:state_pressed="false"
              android:drawable="@drawable/tab_selected_focused" />
    
    
    <!-- STATES WHEN BUTTON IS PRESSED -->
    
        <!-- Non focused states -->
        <item android:state_focused="false" android:state_selected="false"
              android:state_pressed="true"
              android:drawable="@drawable/tab_unselected_pressed" />
        <item android:state_focused="false" android:state_selected="true"
            android:state_pressed="true"
            android:drawable="@drawable/tab_selected_pressed" />
    
        <!-- Focused states (such as when focused with a d-pad or mouse hover) -->
        <item android:state_focused="true" android:state_selected="false"
              android:state_pressed="true"
              android:drawable="@drawable/tab_unselected_pressed" />
        <item android:state_focused="true" android:state_selected="true"
              android:state_pressed="true"
              android:drawable="@drawable/tab_selected_pressed" />
    </selector>


     برای اندرویدهای 3.0 و بالاتر


    وقتی از اندروید 3.0 یا بالاتر استفاده می کنید، فایل  XML استایل شما ممکن است مانند زیر به نظر برسد:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.Holo">
            <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
        </style>
    
        <!-- ActionBar tabs styles -->
        <style name="MyActionBarTabs"
               parent="@style/Widget.Holo.ActionBar.TabView">
            <!-- tab indicator -->
            <item name="android:background">@drawable/actionbar_tab_indicator</item>
        </style>
    </resources>
    


    برای اندروید های 2.1 و بالاتر

    وقتی از کتابخانه پشتیبان استفاده می کنید، فایل XML استایل شما ممکن است مانند زیر به نظر برسد:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat">
            <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
    
            <!-- Support library compatibility -->
            <item name="actionBarTabStyle">@style/MyActionBarTabs</item>
        </style>
    
        <!-- ActionBar tabs styles -->
        <style name="MyActionBarTabs"
               parent="@style/Widget.AppCompat.ActionBar.TabView">
            <!-- tab indicator -->
            <item name="android:background">@drawable/actionbar_tab_indicator</item>
    
            <!-- Support library compatibility -->
            <item name="background">@drawable/actionbar_tab_indicator</item>
        </style>
    </resources>
    

     

     
    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
  • آن چه در این درس خواهید آموخت:

    1. ذخیره ی اطلاعات وضعیت Activity
    2. بازیابی وضعیت Activity

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

    • پشتیبانی از صفحات نمایش مختلف

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

    دانلود دمو »

    ایجاد دوباره ی Activity

    خیلی کم پیش می آید که activity شما به صورت عادی خاتمه پیدا کند، یعنی کاربر دکمه ی برگشت یا Back را فشار بدهد و خودش برنامه را با فراخوانی متد ()finish خاتمه دهد. سیستم ممکن است activity شما را زمانی که در حالت stopped قرار دارد و مدت زیادی است که از آن استفاده نمی شود، خود به خود خاتمه دهد. سیستم همچنین ممکن است Activity شما را وقتی که برنامه ی فعال یا Activity فعال نیاز به منابع بیشتری دارد برنامه ی شما را خود به خود خاتمه دهد بنابراین سیستم اندروید برای بازیابی حافظه ممکن است برنامه های پس زمینه را خاتمه دهد.

    هنگامی که activity با استفاده از دکمه ی برگشت خاتمه پیدا می کند، یا اینکه خود Activity خودش را خاتمه می دهد، نمونه ی activity برای همیشه از بین رفته است، زیرا این گونه خاتمه مبین آن است که Activity بیشتر از این نیاز نبوده است. با این وجود، اگر سیستم به خاطر برخی از محدودیت ها activity را خاتمه دهد، آنگاه اگرچه نمونه واقعی activity از بین رفته است، اما سیستم به خاطر می آورد که این Activity قبلاً وجود داشته است (مانند زمانی که کاربر به آن باز می گردد)، بنابراین سیستم با استفاده از مقادیر ذخیره شده ی مربوط به وضعیت Activity قبل از خاتمه ی آن، یک نمونه ی جدید از activity را ایجاد می کند. داده های ذخیره شده ای که در سیستم اندروید استفاده می شود تا وضعیت قبلی بازیابی شود را اصطلاحاً "instance state" می نامند و در حقیقت مجموعه ای از زوج های کلید مقدار هستند که در شیء Bundle ذخیره شده است. 

    Note

    هشدار: هربار که کاربر صفحه ی نمایش را می چرخاند، Activity از بین می رود و مجدداً ایجاد می شود. هنگامی که جهت صفحه ی نمایش تغییر پیدا می کند، سیستم Activity فعال و پیش روی صفحه نمایش را از بین می برد و آن را دوباره ایجاد می کند، زیرا تنظیمات پیکربندی صفحه ی نمایش تغییر یافته است و Activity شما می بایست، منابع جدیدی (مانند چیدمان) را بارگذار کند.


    به طور پیش فرض، سیستم از وضعیت Bundle برای ذخیره ی اطلاعات مربوط به شیء View در چیدمان activity استفاده می کند (مانند متن داخل شیء EditText). بنابراین، اگر نمونه ی Activity شما  از بین رفت و مجدداً ایجاد شد، وضعیت چیدمان به حالت قبل برمی گردد بدون اینکه نیاز باشد شما کدی را بنویسید. با این وجود، ممکن است Activity اطلاعات بیشتری برای آن وضعیت داشته باشد که می بایست بازیابی شود، مانند متغیرهایی که میزان پیشرفت کاربر در activity را نشان می دهد.

    Note

    توجه: به خاطر اینکه سیستم اندروید وضعیت view ها را در activity شما بازیابی کند، هر view می بایست یک شناسه ی منحصر بفرد داشته باشد،این شناسه توسط خصوصیت android:id فراهم شده است.

    برای ذخیره ی اطلاعات بیشتر در مورد وضعیت Activity، شما می بایست متد را ()onSaveInstanceState لغو و بازنویسی کنید. سیستم هنگامی که کاربر در حال ترک activity است این متد را فراخوانی می کند، و شیء Bundle را به آن ارسال می کند تا زمانی که Activity به صورت ناخواسته از بین رفت این شیء ذخیره شود. اگر سیستم مجبور شد که نمونه ی activity را در زمان های آتی مجدداً ایجاد کند، هم به متد  ()onCreate و هم به متد ()onRestoreInstanceState شیء Bundle را پاس می دهد.

    توضیح شکل:وقتی سیستم شروع به توقف activity شما کرد، سیستم متد ()onSaveInstanceState را فراخوانی می کند (1) بنابراین شما می توانید اطلاعات بیشتری در مورد وضعیت را برای وقتی که Activity قرار است مجدداً ایجاد شود را ذخیره کنید. اگر Activity از بین رفت و Instance مشابهی می بایست ایجاد شود، سیستم اطلاعات وضعیتی که در مرحله (1) ذخیره شده بود را هم برای متد ()onCreate ارسال می کند (2) و هم برای متد ()onRestoreInstanceState ارسال می کند(3).


    ذخیره ی اطلاعات وضعیت Activity

    هنگامی که Activity متوقف شد، سیستم متد ()onSaveInstanceState را فراخوانی می کند، بنابراین Activity می تواند اطلاعات وضعیت را با استفاده از مجموعه ای از مقادیر کلید-مقدار ذخیره کند. در پیاده سازی پیش فرض این متد، اطلاعات وضعیت سلسله مراتب view مانند متن داخل EditText یا مکان اسکرول ListView ذخیره می شود.

    برای ذخیره سازی اطلاعات بیشتر در مورد وضعیت، شما می بایست متد ()onSaveInstanceState را پیاده سازی کنید و زوج های کلید مقدار را به شیء Bundle اضافه کنید. مثال زیر دقیق تر مطلب فوق را بیان می کند:



    مثال پیاده سازی ()onSaveInstanceState

     
    staticfinalString STATE_SCORE="playerScore";
    staticfinalString STATE_LEVEL="playerLevel";
    ...

    @Override
    publicvoid onSaveInstanceState(Bundle savedInstanceState){
       
    // Save the user's current game state
        savedInstanceState
    .putInt(STATE_SCORE, mCurrentScore);
        savedInstanceState
    .putInt(STATE_LEVEL, mCurrentLevel);
       
       
    // Always call the superclass so it can save the view hierarchy state
       
    super.onSaveInstanceState(savedInstanceState);
    }

    Note

    هشدار: همواره پیاده سازی مربوط به SupperClass (کلاسی که Activity از آن ارث بری می کند) را فراخوانی کنید. با این کار اطلاعات مربوط به وضعیت سلسله مراتبی view ذخیره می شود.


    بازیابی وضعیت Activity

    هنگامی که Activity از بین رفت و مجدداً ایجاد شد، می توانید وضعیت ذخیره شده ی آن را از با استفاده از شیء Bundle که سیستم برای آن Activity پاس می دهد بازیابی کنید. هم متد ()onCreate و هم متد ()onRestoreInstanceState شیء Bundle مشابهی را که حاوی اطلاعات وضعیت activity است را دریافت می کنند.

    متد ()onCreate در دو حالت صدا زده می شود: هم موقعی که سیستم یک نمونه ی جدید ایجاد می کند و هم موقعی که سیستم یک نمونه Activity قبلی را مجدداً ایجاد می کند، بنابراین شما می بایست قبل از اینکه شروع به خواندن از شیء Bundle کنید، چک کنید که آیا Bundle تهی است یا نه. اگر تهی بود، سیستم در حال ایجاد یک یک نمونه ی جدید از Activity است، در غیر این صورت سیستم می بایست وضعیت قبلی Activity را بازیابی کند.

    مثال زیر، نحوه ی بازیابی برخی از اطلاعات مربوط به وضعیت را در متد ()onCreate نشان می دهد:



    مثال بازیابی اطلاعات وضعیت

     
    @Override
    protectedvoid onCreate(Bundle savedInstanceState){
       
    super.onCreate(savedInstanceState);// Always call the superclass first
       
       
    // Check whether we're recreating a previously destroyed instance
       
    if(savedInstanceState!=null){
           
    // Restore value of members from saved state
            mCurrentScore
    = savedInstanceState.getInt(STATE_SCORE);
            mCurrentLevel
    = savedInstanceState.getInt(STATE_LEVEL);
       
    }else{
           
    // Probably initialize members with default values for a new instance
       
    }
       
    ...
    }

    ممکن است بخواهید به جای بازیابی اطلاعات وضعیت در متد ()onCreate از متد ()onRestoreInstanceState استفاده کنید.

    سیستم این متد را بعد از متد ()onStart فراخوانی می کند.

    سیستم متد ()onRestoreInstanceState را تنها اگر وضعیت ذخیره شده ای برای بازیابی وجود داشته باشد بازیابی می کند، بنابراین در این حالت نیاز نیست بررسی کنید که آیا شیء Bundle تهی است یا نه.

    Title

    Code
    publicvoid onRestoreInstanceState(Bundle savedInstanceState){
       
    // Always call the superclass so it can restore the view hierarchy
       
    super.onRestoreInstanceState(savedInstanceState);
       
       
    // Restore state members from saved instance
        mCurrentScore
    = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel
    = savedInstanceState.getInt(STATE_LEVEL);
    }
     
    Note

    هشدار: همواره پیاده سازی ()onRestoreInstanceState مربوط به SupperClass (کلاسی که Activity از آن ارث بری می کند) را فراخوانی کنید. با این کار اطلاعات مربوط به وضعیت سلسله مراتبی view که قبلاً به صورت خودکار ذخیره شده بود بازیابی می شود.

    READ MORE
  • افزودن دکمه های Action

    آموزش اندروید و دکمه های Action

    آن چه در این آموزش فرا می گیرید:

    1. مشخص کردن Actionها در XML
    2.  افزودن Actionها به Action Bar
    3. پاسخ به دکمه های Action
    4. دکمه ی برگشت برای Activity های سطح پایین

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

    • فراهم کردن برگشت به activity قبلی

    action bar به شما اجازه می دهد تا دکمه هایی را برای آیتم های action مرتبط با فعالیت جاری برنامه اضافه کنید. عناصری که مستقیماً در action bar با استفاده از یک آیکن یا متن نمایش داده می شوند به دکمه های action مشهور هستند. actionهایی که در action bar جا نمی گیرند و یا به اندازه ی کافی مهم نیستند در action overflow مخفی می شوند.


     مشخص کردن Actionها در XML

    همه ی دکمه های action و آیتم های موجود در action overflow در XMLی با عنوان menu resource تعریف شده اند. برای افزودن actionها به action bar یک فایل XML جدید داخل دایرکتوری res/menu/ ایجاد کنید.

    به ازای هر آیتمی که قصد دارید در action bar ایجاد کنید، یک عنصر <item> اضافه نمایید. برای مثال:

    res/menu/main_activity_actions.xml


    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <!-- Search, should appear as action button -->
        <item android:id="@+id/action_search"
              android:icon="@drawable/ic_action_search"
              android:title="@string/action_search"
              android:showAsAction="ifRoom" />
        <!-- Settings, should always be in the overflow -->
        <item android:id="@+id/action_settings"
              android:title="@string/action_settings"
              android:showAsAction="never" />
    </menu>

    قطعه کد بالا نشان می دهد که action مربوط به Search می بایست به صورت یک دکمه و هنگامی که room در action bar ظاهر شد، نمایش داده شود، اما action مربوط به Settings همواره نمایش داده می شود. (به صورت پیش فرض، همه ی action ها در overflow نمایش داده می شود، اما اگر به طور صریح مشخص کنید که چه action ی در overflow نمایش داده شود، یک تمرین خوبی بشمار می آید.)

    خصوصیت icon به یک ID منبع برای تصویر احتیاج دارد. نامی که به دنبال drawable@ می آید می بایست نام تصویری باشد که در دایرتکتوری res/drawable ذخیره شده است. برای مثال، "drawable/ic_action_search@" به ic_action_search.png اشاره می کند. به همین ترتیب، خصوصیت title از یک رشته منبع استفاده می کند که در فایل XML داخل دایرکتوری res/values تعریف شده است.

    Note

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

    اگر برنامه ی شما از کتابخانه های پشتیبان استفاده می کند برای سازگاری با نسخه های پایین اندروید مانند 2.1، خصوصیت showAsAction در فضای نام android: وجود ندارد. در عوض این خصوصیت در کتابخانه پشتیبان وجود دارد و شما می توانید فضای نام XML خودتان را تعریف کنید و از فضای نام به عنوان پیشوند خصوصیت استفاده کنید. برای مثال:

    res/menu/main_activity_actions.xml

     استفاده از فضای نام

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
        <!-- Search, should appear as action button -->
        <item android:id="@+id/action_search"
              android:icon="@drawable/ic_action_search"
              android:title="@string/action_search"
              yourapp:showAsAction="ifRoom"  />
       ...
    </menu>


     افزودن Actionها به Action Bar

    برای قرار دادن آیتم های منو در action bar، متد ()onCreateOptionsMenu را در activity پیاده سازی کنید. در این متد آیتم منو، در منو قرار داده می شود. این کار به وسیله ی inflator انجام می شود. مثلاً:

     

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu items for use in the action bar
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_activity_actions, menu);
        return super.onCreateOptionsMenu(menu);
    }
    
     

    پاسخ به دکمه های Action

    هنگامی که کاربر روی یکی از دکمه های Action یا آیتم های دیگر در action overflow کلیک می کند، سیستم متد ()onOpitonsItemSelected مربوط به activity شما را صدا می زند. وقتی دارید این متد را پیاده سازی می کنید، متد ()getItemId را فراخوانی کنید تا مشخص شود روی کدام آیتم کلیک شده است (ID برگردانده شده با مقداری که در خصوصیت android:id عنصر <item> مساوی می باشد.)

    Title

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
        switch (item.getItemId()) {
            case R.id.action_search:
                openSearch();
                return true;
            case R.id.action_settings:
                openSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    } 
    private void openSettings() {
            // TODO Auto-generated method stub
             Toast.makeText(this, "Open Setting button pressed", Toast.LENGTH_SHORT).show();
        }


    private void openSearch() {
            // TODO Auto-generated method stub
             Toast.makeText(this, "Search button pressed", Toast.LENGTH_SHORT).show();
        }
     

    افزودن دکمه ی برگشت برای Activity های سطح پایین


    دکمه ی برگشت در Gmail

    تمام صفحات برنامه ی شما که ورودی اصلی برنامه نمی باشند (فعالیتهایی که در حقیقت "صفحه ی اصلی" نیستند) می بایست به کاربر با استفاده از دکمه ی UP در action bar راهی برای برگشت به صفحه ی والدشان ارائه دهند.

    وقتی که از اندریود 4.1 یا بالاتر استفاده می کنید و یا هنگامی که از ActionBarActivity کتابخانه ی پشتیبان استفاده می کنید، پیاده سازی دکمه ی UP خیلی ساده و از طریق تعریف Activity والد در فایل manifest و فعال سازی دکمه UP در Action bar امکان پذیر است.

    برای مثال، در زیر نحوه ی تعریف activity والد را در فایل manifest ملاحظه می فرمایید:

    Title

    <application... >
       ...
        <!-- The main/home activity (it has no parent activity) -->
        <activity
            android:name="com.example.myfirstapp.MainActivity"...>
           ...
        </activity>
        <!-- A child of the main activity -->
        <activity
            android:name="com.example.myfirstapp.DisplayMessageActivity"
            android:label="@string/title_activity_display_message"
            android:parentActivityName="com.example.myfirstapp.MainActivity" >
            <!-- Parent activity meta-data to support 4.0 and lower -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.myfirstapp.MainActivity" />
        </activity>
    </application>
    
     

    سپس آیکن را به عنوان دکمه ی UP با صدا زدن متد ()setDisplayHomeAsUpEnabled فعال کنید:

    Title


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_displaymessage);
    
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        // If your minSdkVersion is 11 or higher, instead use:
        // getActionBar().setDisplayHomeAsUpEnabled(true);
    }
     

    به این دلیل که سیستم حالا می داند که MainActivity والد DisplayMessageActivity می باشد، هنگام کلیک روی دکمه ی UP در این activity، سیستم به Activity والد بر می گرددو نیاز نیست که رویداد مربوط به دکمه ی UP را مدیریت و هندل کنید

    READ MORE
  • پیش نیازها

    1. آموزش اندروید-ایجاد پروژه اندروید
    2. آموزش اندروید-ایجاد اولین برنامه

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

    • Activityها

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

    دانلود دمو »

    آموزش اندروید - مدیریت چرخه حیات Activity

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

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

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

    READ MORE
تمامی محصولات و خدمات این وبسایت، حسب مورد دارای مجوزهای لازم از مراجع مربوطه می‌باشند و فعالیت‌های این سایت تابع قوانین و مقررات جمهوری اسلامی ایران است.
logo-samandehi مجوز نشر دیجیتال از وزرات فرهنگ و ارشاد اسلامی پرداخت آنلاین -  بانک ملت معرفی بیاموز در شبکه سه