ساخت تولبار (Toolbar) متریال دیزاین
ویجت تولبار یا Toolbar جایگزین نسخه قدیمی آن یعنی ActionBar است. به دلیل آنکه تولبار به صورت یک View در اکتیویتی تعریف میشود، توسعه دهنده و برنامه نویس دست باز تری در مدیریت آن داشته و ویرایش آن نسبت به اکشن بار ساده تر شده. تولبار همان نوار بالای صفحه بوده که میتواند شامل عنوان صفحه (title)، لوگو، منو، گزینه جستجو و… باشد. در این فصل به نحوه ساخت تولبار (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>
در حال حاضر 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 اضافه کرد:
من در محیط 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) می توانیم به این مقادیر دسترسی داشته باشیم.
در تصویر بالا مشاهده می کنید تولبار با ارتفاعی برابر با ارتفاع اکشن بار اولیه، به صفحه اضافه شده اما رنگ پس زمینه ندارد. پس یک بک گراند به تولبار اضافه می کنم:
<android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:id="@+id/m_toolbar" android:background="?attr/colorPrimary"/>
من بازهم از رنگی که قبلا برای پس زمینه اکشن بار بکار رفته بود استفاده کردم:
البته رنگ را با @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 را انتخاب کنید:
پروژه را مجدد اجرا می کنم:
این ساده ترین حالت یک تولبار است که نام اپلیکیشن نیز در قسمت 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"/>
(تغییرات اعمال شده روی تصویر بالا محسوس نیست)
اضافه کردن منو (Menu) به تولبار
مهمترین ویژگی دیگر تولبار، منوها هستند و توسعه دهنده قادر است به تعداد موردنیاز و در حالت های مختلف، گزینه هایی را در قالب Menu به تولبار اضافه کند. منو ها در قالب فایل xml و در دایرکتوری menu به پروژه اضافه می شوند. روی دایرکتوری res راست کلیک کرده و
New > Android resource file را انتخاب می کنم:
در قسمت File name یک نام دلخواه وارد کردم. با انتخاب گزینه Menu در قسمت Resource type، به صورت خودکار Directory name نیز menu انتخاب می شود و با تایید تنظیمات، دایرکتوری و فایل مربوطه ایجاد می شود:
گزینه های مدنظر را در قالب 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>
در تصویری بالا مشاهده می کنید منو به تولبار اضافه شده اما در حال حاضر فقط در Preview فایل menu_toolbar.xml این منو اضافه شده و برای نمایش باید آن را به اکتیویتی اضافه کنم. این کار توسط متد onCreateOptionsMenu انجام می شود. این متد و سایر متدهای موجود در اندروید را از مسیر Code > Override Methods می توانیم انتخاب و به پروژه اضافه کنیم:
کافیست روی این پنجره چند کاراکتر اول متد را تایپ کرده تا گزینه مدنظر درون لیست نمایش داده شود. راه دیگر هم اضافه کردن دستی متد به اکتیویتی است:
@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 می کنم:
آیکون منو به درستی به سمت راست تولبار اضافه شد که با لمس آن، گزینه های تعریف شده نمایش داده می شود:
در حال حاضر با لمس گزینه های 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); }
جهت مطالعه ادامه آموزش، فایل PDF را دانلود نمائید
توجه : سورس پروژه پوشه Exercises قرار داده شده است.
با توجه به اینکه آموزشهای پایه با قیمت پایین در اختیار کاربر قرار گرفته و درآمد حاصل صرف تامین هزینه های وب سایت و تهیه آموزش های آتی می شود، به اشتراک گذاری این فایل با دیگران خلاف اخلاق خواهد بود.
تعداد صفحات : ۵۲
حجم : ۲ مگابایت
قیمت : ۱۸ هزار تومان
توجه: صرفا در صورتی از درگاه پشتیبان استفاده کنید که قادر به پرداخت از طریق سبد دانلود نباشید.
افزودن به سبد دانلود درگاه پشتیبان
سلام استاد ممنونم از اموزش خوبتون
اون رنگ بالای تولبار رو چجوری میشه عوض کرد؟
آموزش رو با دقت مطالعه کنید. به این مورد اشاره شده
سلام
سوالی داشتم
برای استفاده از تولبار یک استایل ایجاد کردم و دستورات لازم رو نوشتم
اما برای منوی تولبار بر به مشکل خوردم
به تمام منوها آیکون دادم ولی نمایش نمیده
فقط گزینهی دومم یک منوی دیگه هست
یعنی اگر روی گزینهی دوم کلیک بشه یک پاپآپ منوی دیگه باز میشه، خوی این پاپآپ منوی جدید آیکون ها رو نمایش میده ولی توی پاپ آپ منوی اصلی هیچ آیکونی رو نمایش نمیده مشکل چیه ؟
شاید آدرس دهی برای آیکونها اشتباه هست. یا مثلا آیکون ها هم رنگ پس زمینه تولبار هستن و دیده نمیشن
سلام
من در ساخت دکمه backمشکل دارم وقتی این کدgetSupportActionBar().setDisplayHomeAsUpEnabled(true);رو میزنم که اصالتا دکه backباید ساخت بشه بدون عملکرد وقتی برنامه رو اجرا میکنم برنامه درحال اجرا از برنامه خارج میشه ومیزنه برنامه متوقف شد
موقع اجرای برنامه روی شبیه ساز یا دیوایس حقیقی، Logcat رو بررسی کنید ببینید علت کرش کردن برنامه چی هست و مربوط به کدوم قسمته
هم با شبیه ساز رفتم و هم دیواس واقعی وقتی کد رو میزنم برنامه کراش میده وقتی کدو کامنت میکنم به راحتی اجرا میشه
عرض کردم خدمتتون. لاگ کت رو بررسی کنید ببینید علتش چیه. یعنی ببینید در اروری که میگیرید و مربوط به این تکه کد هست، به چه دلیل باعث کرش میشه. ممکنه با یک نسخه از اندروید سازگاری نداشته باشه یا…
عذرخواهی میکنم. واقعا چه معنایی داره بابت هر کلمهی که به دیگران منتقل میکنید باید پول بگیرید.همین موارد همه و همه و با تمام جزئیاتش تو سایت developer.android.com هستند.اصلا چیزی تو اندروید نیست مگر اینکه تو سایتdeveloper.android.com گفته شده.،گه کسی هم انگلیسی بلد نیست گوگلترانس هم در خدمت همه هست.
ممنون از انتقادتون. حدود کمتر از ۳۰ درصد تعداد مباحث آموزشی غیر رایگان هست. شما میتونید در منوی بالا، گزینه آموزش های رایگان رو انتخاب کنید و فقط موراد رایگان رو استفاده کنید.
عالی توضیح دادید………
تشکر
سلام ،من میخوام فقط Action barیا Toolbar ی activityپاک بشه اما وقتی ک ان کاری ک گفتیدو میکنم برای همه activityهام پاک میشه و زمانی ک میخوام برناممو اجرا کنم crashمیکنه
وقتی تم رو NoActionBar تعریف میکنید برای همه اکتیویتی ها اعمال میشه
سلام . من وقتی میخوام نمونه Toolbar رو بسازم گزینه مربوط به support نمیاد . فقط گزینه ویجت داره . کتابخانه appcompat هم دانلود شده . مشکل کجاست ؟
https://android-studio.ir/androidx-migration-guide
این مبحث رو مطالعه بفرمائید
سلام ahmadreza از برنامه Adobe XD استفاده کنید.
سلام
بابت آموزشای خیلی خوبتون ممنون وسپاسگذارم
استاد من هرکاری کردم نتونستم کتابخونه متریال دیزاین نسخه۲۶٫۱٫۰روتهیه کنم میشه توسایتتون قرار بدین که دانلودش کنیم ممنون
خیر باید توسط خود اندروید استودیو دانلود بشه
استاد سلام ممنون از آموزش خوبتنون . ی سوال داشتم چجوری رنگ متن و رنگ آیکون ها و شکل آیکون های منو رو تغییر بدیم؟
مبحث رابط کاربری رو مطالعه کنید
سلام
من دارم روی یه پروژه کار می کنم که تعداد زیادی activity داره
به نظرم اینکه توی هر activity بخواهیم تگ toolbar رو توی فایل xml اد کنیم و داخل خود کلاس جاوا هم توابع onCreateOptionsMenu و onOptionsItemSelected رو Ovverride کنیم روش خیلی وقتگیریه.
راه حلی واسه حل این مششکل ندارید؟
https://codereview.stackexchange.com/a/146226
سلام. من منو تولبار رو طبق اموزش هایی که دادین وارد اکتیویتی کردم. ولی تو خروجی فقط تولبار رو نشون میده. منو نیست.
احتمال زیاد یک نکته ریز رو از قلم انداختید. به دقت بررسی کنید. یکبار هم سورس رو ایمپورت و اجرا کنید ببینید آیا سورس هم همین مشکل رو داره براتون؟
سلام . ممنون بابت آموزشهاتون
من یه مشکلی دارم
تمام مراحل رو مطابق آموزش های شما پیش میرم اما toolbar موردنظر به هیچ وجه روی قسمت preview دیده نمی شه . ولی وقتی برنامه رو روی شبیه ساز جنی موشن اجرا میکنم مشکلی نداره و toolbar موردنظر هم به درستی ایجاد شده .
با اینکه با toolbar رو با عرض و ارتفاع های مختلفی ساختم و امتحان کردم اما هیچ کدوم در قسمت preview نمایش داده نمی شه و مثل یه نقطه کوچیک بالا سمت چپ صفحه میمونه و دیده میشه
API بالای Preview رو آزمایشی تغییر بدید احتمالا اوکی میشه
سلام و درود خدمت استاد عزیز
یک سوال: چطور وقتی از طریق منو وارد یک اکتویتی میشیم، گزینه مربوط به اون اکتیویتی را از لیست آیتم های منو حذف کنیم؟
خارج از این مبحث هست بزرگوار. لازمه سرچ کنید
سلام خسته نباشید من تازه اندروید را شروع کردم برنامهtoolbarرا نوشتم همراه با fragmentولی وقتی میخوام اجرا بگیرم پیغام متوقف شدن برنامه را ارسال میکنه هم روی شبیه ساز امتحان کردم و هم روی گوشی. ممنونم ازتون
درست می فرمایید از همین متد استفاده کردم.
عرض کردم بعد از استفاده از این متد اون دکمه بازگشت به اکتیویتی قبل هم به سمت راست منتقل شده حالا چطور باید بردش سمت چپ؟
در این مورد سرچ کردم ولی به نتیجه نرسیدم.
عرض سلام و خسته نباشید.
بعد از راست چین کردن تولبار دکمه بازگشت میاد سمت راست.
اگه بخواهیم سمت چپ باشه و تایتل تولبار راست چین بشه باید چیکار کرد؟
سرچ کنید android rtl toolbar احتمالا آموزشش پیدا بشه
سلام
کلا خیلی با اموزشاتون حال کردم
خواستم بددونم
setSupoortactionbar
داخل ورژن جدید امتحانش کردید ؟
ارور میده
اندروید استادیو ورژن ۳٫۱
بله. deprecate نشده. ببینید چه اروری میگیرید و ترجمش کنید. نباید چیز خاصی باشه
سورس اندروید برا من باز نمیشه
ارورهایی که میگیرید رو با توجه به ابزاری که در SDK دارید رفع کنید. اگر موفق نشدید، یه پروژه جدید بسازید، فایلهای هم نام با فایلهای java و xml سورس ایجاد کنید و محتوای هر فایل رو به فایل همنام پروژه منتقل کنید.
http://s9.picofile.com/file/8320621050/Untitled.jpg
همینجور میمونه
قبل از اینکه پروژه رو ایمپورت کنید، دو فایل build.gradle در فولدر اصلی سورس و فولدر app رو با یه ادیتور باز کنید و ورژن gradle و سایر موارد رو به ورژنی تغییر بدید که در build.gradle پروژه های خودتون هست. بعد ایمپورت کنید
سلام اموزش خوبی بود فقط چرا ایکون ها نمیان روی تولبار؟
حتما یه جای کارتون ایراد داره
سلام خسته نباشید ببخشید میخواستم بپرسم که ایا روش یا برنامه یا راه حلی هست که بتونیم به صورت ساده و تخصصی بر روی طراحی رابط کاربری اپ کار کنیم و بعد از اون وارد اندروید استیدو کنیم و بهش کد بدیم؟ یا باید همه موارد رو از اول داخل اندروید استدیو طراحی کنیم؟
بنده اطلاعی ندارم متاسفانه
با سلام وقتی سورس پروزه رو ران میکنم یه ارور پلتفرم میده وقتی آپدیت میکنم
بهم ارور
refresh failed
میده
چیکار کنم ؟
کتابخانه هایی که در SDK شما موجود هست با نسخه سورس متفاوته. build.gradle سورس و یه پروژه که خودتون ساختید رو مقایسه و بر اساس اون، ورژن لابرری های سورس رو اصلاح کنید
خیلی آموزش خوبی بود ، ممنون
با سلام من تو ی اکتیویتی از ۲ تا تولبار استفاده کردم ایا راهی داره برای هر ۲ تا تولبار بشه منو اضافه کرد؟ چون از کد منو که استفاده میکنم برای تولبار اولی اضافه میشه