متریال دیزاین : بخش سوم : ساخت تولبار (Toolbar)

در این فصل به نحوه ساخت تولبار (Toolbar) در اندروید و جایگزینی آن با ActionBar پیش فرض اندروید می پردازیم که شامل مباحث زیر می باشد:

  • معرفی اکشن بار و تولبار در اندروید
  • حذف اکشن بار و اضافه کردن تولبار به اکتیویتی
  • آشنایی با منو (Menu) در اندروید و نحوه کار با منوها در تولبار
  • نحوه کار با PopUp Menu (پاپ آپ منو) یا Options Menu
  • ست کردن آیکون روی آیتم های منو
  • آشنایی با آیکونهای PNG و XML Vector و نحوه مدیریت آنها
  • معرفی متدهای onCreateOptionsMenu و onOptionsItemSelected
  • مدیریت نحوه چینش آیتم های منو در تولبار
  • نحوه تغییر آیکونهای پیش فرض تولبار
  • آشنایی با استایل دهی به تولبار و عناصر آن
  • نحوه اضافه کردن لوگو، زیرعنوان و Title سفارشی به تولبار

این فصل در قالب PDF و در ۵۲ صفحه تهیه شده که در ادامه چند صفحه ی ابتدایی این مبحث قرار داده شده:

اکشن بار (ActionBar):

به نام خدا. در مبحث گذشته تا حدودی با اکشن بار (ActionBar) آشنا شدیم. اکشن بار به صورت پیش فرض در بالای اکتیویتی ها قرار دارد و توسعه دهنده می تواند آنرا شخصی سازی کند؛ از جمله اضافه کردن عنوان (Title) اکتیویتی، لوگو، منو و… . امکان مدیریت و شخصی سازی اکشن بار در لایه طراحی (xml) اکتیویتی وجود نداشت و همین باعث می شد کار برای برنامه نویس تا حدودی پیچیده باشد.

تولبار (Toolbar):

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

تولبار جایگزینی برای اکشن بار است که در اندروید Lollipop (API 21) معرفی شد. بر خلاف اکشن بار، تولبار یک view است و مانند سایر view ها در layout تعریف می شود. به همین دلیل توسعه دهنده به سادگی می تواند تولبار را در هرجای اکتیویتی که مدنظر دارد اضافه کند و خواص موردنیاز را نیز را به تولبار اختصاص دهد. تولبار و اکشن بار در ظاهر تفاوتی با یکدیگر ندارند و فقط نحوه اضافه کردن آنها به اکتیویتی متفاوت است.

یک پروژه با نام Toolbar می سازم و قسمت های مختلف را با هم بررسی می کنیم.

اکشن بار پیش فرض اندروید

در ابتدا ActionBar پیش فرض اندروید بالای اکتیویتی نمایش داده می شود که لازم است قبل از اضافه کردن Toolbar، آنرا حذف کنیم. حذف اکشن بار را در جلسه گذشته انجام دادیم. کافی ست تم AppTheme به جای DarkActionBar از NoActionBar ارث بری کند:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

تم NoActionBar متریال اندروید

در حال حاضر layout اکتیویتی به اینصورت است:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="ir.android_studio.toolbar.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

</LinearLayout>

حالا باید یک view از جنس Toolbar به لایه اضافه کنم که هم در محیط Design و از قسمت Palette می توان یک Toolbar را کشیده و روی صفحه رها کرد و هم اینکه در حالت Text، یک تگ android.support.v7.widget.Toolbar به layout اضافه کرد:

اضافه کردن Toolbar به اکتیویتی

من در محیط Text و به صورت دستی اضافه می کنم:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="ir.android_studio.toolbar.MainActivity">

    <android.support.v7.widget.Toolbar 
        
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

</LinearLayout>

در قدم بعد ارتفاع، عرض و id را تعریف می کنم:

<android.support.v7.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:id="@+id/m_toolbar"/>

عرض را match_parent تعریف کردم تا تمامی عرض اکتیویتی را دربر گیرد. برای ارتفاع به جای اینکه عددی را درنظر بگیرم، از مقدار پیش فرض موجود در Theme اندروید استفاده می کنم که با نام actionBarSize تعریف شده و توسط ?attr/ (مخفف attribute) می توانیم به این مقادیر دسترسی داشته باشیم.

اضافه کردن Toolbar به اکتیویتی

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

<android.support.v7.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:id="@+id/m_toolbar"
    android:background="?attr/colorPrimary"/>

من بازهم از رنگی که قبلا برای پس زمینه اکشن بار بکار رفته بود استفاده کردم:

تعریف background تولبار اندروید

البته رنگ را با @color هم می شود به view اضافه کرد:

android:background="@color/colorPrimary"

تا اینجای کار من فقط view مربوط به تولبار را به layout اضافه کرده ام. مانند سایر view ها (دکمه و…) تولبار نیز باید داخل اکتیویتی تعریف شود:

package ir.android_studio.toolbar;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.m_toolbar);
        setSupportActionBar(mToolbar);

    }
}

من یک نمونه از Toolbar با نام mToolbar ساخته و سپس آنرا به id تولبار متصل کردم. در قدم بعد توسط متد setSupportActionBar، تولبار را به عنوان اکشن بار معرفی می کنم. در حقیقت در اینجا ما تولباری که خودمان ساختیم را جایگزین اکشن بار می کنیم. دقت داشته باشید هنگام ساخت نمونه از Toolbar، گزینه مربوط به کتابخانه Support را انتخاب کنید:

ساخت یک نمونه از Toolbar در اکتیویتی

پروژه را مجدد اجرا می کنم:

اضافه شدن Title تولبار

این ساده ترین حالت یک تولبار است که نام اپلیکیشن نیز در قسمت Title نمایش داده می شود.
قبلا با ویژگی های متریال دیزاین آشنا شدیم. یکی از ویژگی های این سبک، ارتفاع دادن به عناصر است. توسط خاصیت elevation یک سایه زیر تولبار اضافه می کنم تا بنظر برسد تولبار از سطح صفحه مقداری بالا آمده و دارای ارتفاع است:

<android.support.v7.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:id="@+id/m_toolbar"
    android:background="?attr/colorPrimary"
    android:elevation="3dp"/>

افزودن خاصیت elevation به تولبار

(تغییرات اعمال شده روی تصویر بالا محسوس نیست)

اضافه کردن منو (Menu) به تولبار

مهمترین ویژگی دیگر تولبار، منوها هستند و توسعه دهنده قادر است به تعداد موردنیاز و در حالت های مختلف، گزینه هایی را در قالب Menu به تولبار اضافه کند. منو ها در قالب فایل xml و در دایرکتوری menu به پروژه اضافه می شوند. روی دایرکتوری res راست کلیک کرده و
New > Android resource file را انتخاب می کنم:

ایجاد فایل menu.xml در پروژه اندروید

در قسمت File name یک نام دلخواه وارد کردم. با انتخاب گزینه Menu در قسمت Resource type، به صورت خودکار Directory name نیز menu انتخاب می شود و با تایید تنظیمات، دایرکتوری و فایل مربوطه ایجاد می شود:

ایجاد فایل menu.xml در پروژه اندروید

گزینه های مدنظر را در قالب item ها به تگ menu اضافه می کنیم. من دو گزینه آزمایشی تعریف کردم:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:title="Settings"
        android:id="@+id/setting" />

    <item
        android:title="About"
        android:id="@+id/about" />

</menu>

اضافه شدن item های منو

در تصویری بالا مشاهده می کنید منو به تولبار اضافه شده اما در حال حاضر فقط در Preview فایل menu_toolbar.xml این منو اضافه شده و برای نمایش باید آن را به اکتیویتی اضافه کنم. این کار توسط متد onCreateOptionsMenu انجام می شود. این متد و سایر متدهای موجود در اندروید را از مسیر Code > Override Methods می توانیم انتخاب و به پروژه اضافه کنیم:

اضافه کردن متد onCreateOptionsMenu به اکتیویتی

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

اضافه کردن متد onCreateOptionsMenu به اکتیویتی

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return super.onCreateOptionsMenu(menu);
}

متد را خالی کرده و به اینصورت تکمیل می کنم:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.toolbar_menu, menu);
    return true;

}

توسط متد getMenuInflater و سپس inflate، فایل toolbar_menu را به عنوان منو معرفی می کنم. مشابه R.id برای تعریف منوها از R.menu استفاده می کنیم. در نهایت menu را به متد onCreateOptionsMenu پاس می دهیم. چون متد از نوع boolean است نیاز به return دارد.
پروژه را Run می کنم:

منو به تولبار اندروید اضافه شد

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

پاپ آپ منو، PopUp Menu، Options Menu

در حال حاضر با لمس گزینه های Settings و یا About هیج اتفاقی نمی افتد که لازم است آیتم ها را هندل کنیم. یعنی با کلیک روی هر گزینه، یه کد اجرا شود. برای این کار لازم است متد onOptionsItemSelected را به اکتیویتی اضافه کنیم. مطابق آنچه قبلا توضیح داده شد، این متد را به MainActivity اضافه می کنم:

package ir.android_studio.toolbar;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.m_toolbar);
        setSupportActionBar(mToolbar);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return super.onOptionsItemSelected(item);
    }
}

تصمیم دارم شرط ها را با if else پیاده سازی کنم:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.setting) {
        
    }
    else if (id == R.id.about) {
        
    }

    return super.onOptionsItemSelected(item);
}

ابتدا یک نمونه از جنس int با نام دلخواه id ساخته و برابر item.getItemId() قرار دادم. item.getItemId() آی دی آیتم را گرفته و درون id می ریزد. حالا در if ها برای هر آیتم میتوانیم یک کد و وظیفه مشخص کنیم. من به هرکدام یک Toast اضافه می کنم تا نتیجه را به سادگی نمایش دهم:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.setting) {
        Toast.makeText(getApplicationContext(), "Settings Item Clicked", Toast.LENGTH_SHORT).show();
    }
    else if (id == R.id.about) {
        Toast.makeText(getApplicationContext(), "About Item Clicked", Toast.LENGTH_SHORT).show();
    }

    return super.onOptionsItemSelected(item);
}

اجرای گزینه های منو و نمایش Toast

توجه : سورس پروژه به همراه فایل آموزشی داخل پوشه Exercises قرار داده شده است.

جهت مطالعه ادامه آموزش، فایل PDF را دانلود نمائید.

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

در صورتی که در دانلود از طریق باکس زیر (سبد دانلود) با مشکل مواجه شدید، با مراجعه به این لینک گزینه Toolbar به مبلغ ۱۰۰۰ تومان را انتخاب نمائید.

دانلود فایل آموزشی با فرمت PDF به همراه سورس پروژه
تعداد صفحات : ۵۲
حجم : ۲ مگابایت
قیمت : ۱۰۰۰ تومان

۰۲ دی ۱۳۹۶
سوالاتی که مشمول موارد زیر باشد تایید و پاسخ داده نخواهد شد :
۱ : جزء موارد پاسخ داده شده در مطلب "مشکلات و پرسش های رایج" باشد
۲ : سوال قبلا توسط افراد در دیدگاهها مطرح و پاسخ داده شده باشد
۳ : سوال خارج از مبحث آموزشی موجود در این صفحه باشد

پاسخ دهید

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

کد امنیتی *