کتابخانه MaterialDrawer یک راه سریع برای افزودن Navigation Drawer
منوی کشویی یا همان Navigation Drawer یکی از امکاناتی است که اکثر توسعهدهندگان اندروید آن را در پروژههای خود پیاده سازی میکنند. هرچند روشهای مختلفی برای پیادهسازی navigation drawer وجود دارد ولی در این مطلب میخواهم یکی از آسانترین و سریعترین روشهای پیاده سازی منوی کشویی را آموزش دهم.
در این مطلب ما به کمک کتابخانه MaterialDrawer اقدام به ساخت navigation drawer برای اپ خود میکنیم.
در گام نخست در فایل build.gradle پروژه خود در قسمت dependencies کدهای زیر را وارد کنید:
1 2 3 |
بعد از ایجاد تغییرات در این فایل، پروژه شما sync میشود. بعد از این مرحله اگر مشکلی نبود سراغ گام بعدی میرویم.
نکته: اگر پروژه شما قدیمی باشد و از targetSdkVersion و همچنین compileSdkVersion پایین استفاده کنید gradle از شما پیغام خطا میگیرد. پس درنظر داشته باشید که باید پروژه با آخرین نسخه sdk کامپایل شود. همچنین باید appcompat-v7 و support-v4 هم به آخرین نسخه تغییر کند. بنابراین در این مرحله شاید لازم باشد sdk خود را بهروزرسانی کنید!
(در زمان نوشتن این مطلب targetSdkVersion و compileSdkVersion روی نسخه ۲۳ و appcompat-v7 و support-v4 هر دو روی نسخه ۲۳٫۱٫۰ تنظیم شدهاند.)
نکته ۲: اگر بهدلیل محدودیتها نمیتوانید به صورت مستقیم sdk را بهروزرسانی کنید، میتوانید از این لینک استفاده کنید. بعد از دانلود هر فایل باید آن را در قسمت مناسب در پوشه sdk خود کپی کنید
در گام دوم کدهای زیر را در اکتیویتی که میخواهید منو را نمایش دهید وارد کنید (معمولا MainActivity) و همچنین import مناسب را در پروژه انجام دهید.
1 |
new DrawerBuilder().withActivity(this).build(); |
و تمام! به همین راحتی منوی کشویی شما ساخته شد!
اما در این مرحله منوی ما خالیست و هیچ محتوایی ندارد پس لازم است که یک سری کارها انجام دهیم و منوی کشویی را به شکل دلخواه تغییر دهیم و گزینههای منو را اضافه کنیم.
در ادامه کدهای drawer خودمان را تغییر میدهیم که بتوانیم راحتتر با آن کار کنیم.
در ابتدا یک آبجکت از drawer میسازیم:
1 |
Drawer drawer = null; |
قسمتی که منو را build کردیم به این صورت تغییر میدهیم:
1 |
drawer = new DrawerBuilder().withActivity(this).build(); |
تا اینجای کار چیزی تغییر نکرد. بعد از اجرای پروژه همان نمای قبلی را مشاهده میکنیم.
اما استاندارد این است که در Toolbar یک علامت منو (علامت سه خط زیر هم) قرار بگیرد تا کاربر بداند در برنامه منو وجود دارد و با تپ کردن آن منو باز شود. (من در پروژههایم از Toolbar استفاده میکنم به شما هم توصیه میکنم از toolbar استفاده کنید. در این آموزش هم بر این مبنا جلو میرویم.)
پس قبل از بیلد کردن منو (.build) کد زیر را وارد میکنیم: (در اینجا toolbar همان آبجکتی است که در هنگام ساخت تولبار آن را ایجاد کردیم و از قبل در پروژه ما وجود داشته و ما فقط آن را به drawer پاس دادیم)
1 |
.withToolbar(toolbar) |
حالا علامت منو هم به تولبار اضافه شد و با تپ کردن آن منو باز میشود.
اما اپهای ما فارسی هستند و روش صحیح این است که منو از سمت راست باز شود. برای این منظور از کد زیر استفاده میکنیم:
1 |
.withDrawerGravity(GravityCompat.END) |
نکته: در نسخههای پایین اندروید، راستبهچپ به درستی پشتیبانی نمیشود و توصیه میشود که در این مواقع یکبار بررسی کنید که نسخه اندروید دستگاه کاربر چیست و متناسب با آن منو را راست یا چپ نمایش دهید. مثال:
1 2 3 4 |
int drawerGravity = Gravity.END; if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { drawerGravity = Gravity.START; } |
در کدهای بالا بررسی کردم اگر نسخه api اندروید دستگاه کاربر کمتر یا مساوی ۱۶ بود، مقدار gravity را برابر start (چپ) قرار دادم. یعنی در دستگاههای با نسخه پایینتر یا مساوی ۱۶ (JB) منو سمت چپ و اگر غیر این بود end (راست) نشان داده میشود. با این کار منو و علامت منو در یک طرف خواهند بود.
اما میرسیم به مهمترین مسئله، یعنی اضافه کردن گزینههای منو. برای اضافه کردن آیتمها از addDrawerItems استفاده میکنیم. کدهای ما بعد از اضافه کردن گزینهها به شکل زیر درمیآیند که به توضیح هرکدام خواهم پرداخت:
1 2 3 4 5 6 7 8 9 10 |
.addDrawerItems( new SectionDrawerItem().withName("دفترچه").withTextColor(ContextCompat.getColor(this, R.color.md_grey_500)).withDivider(false), new SecondaryDrawerItem().withName("تنظیمات").withIcon(R.drawable.ic_settings).withSelectable(false), new SectionDrawerItem().withName("موارد دیگر").withTextColor(ContextCompat.getColor(this, R.color.md_grey_500)), new SecondaryDrawerItem().withName("حمایت از برنامه").withIcon(R.drawable.ic_support).withSelectable(false), new SecondaryDrawerItem().withName("ارتباط").withIcon(R.drawable.ic_contact).withSelectable(false), new SecondaryDrawerItem().withName("درباره").withIcon(R.drawable.ic_about).withSelectable(false), new SecondaryDrawerItem().withName("بازخورد").withIcon(R.drawable.ic_feedback).withSelectable(false), new SecondaryDrawerItem().withName("ارتقا به نسخه پیشرفته").withIcon(R.drawable.ic_purchase).withSelectable(false).withIdentifier(8) ) |
ما چند نوع drawer item داریم.
PrimaryDrawerItem
SecondaryDrawerItem
SectionDrawerItem
اسم هرکدام نشاندهنده خاصیت آن است. منوی ما دو قسمت اصلی دارد که SectionDrawerItem نشان دهنده همین قسمتهاست. در این منو ما PrimaryDrawerItem نداریم و فقط از SecondaryDrawerItem استفاده کردیم. ترتیب نمایش آیتمهای منو مانند ترتیب قرار گرفتن کدهاست. یعنی ابتدا عنوان قسمت یا گروه میآید (SectionDrawerItem) و زیر آن گزینه مربوط به همان قسمت (SecondaryDrawerItem).
کارکرد گزینههای withName و WithIcon و withTextColor مشخص هستند.
به صورت پیشفرض بالای SectionDrawerItem خطی قرار میگیرد که هر گروه را از هم جدا کند. چون گروه اول ما در بالا قرار دارد پس لازم نیست خطی بالای آن باشد، پس بهوسیله withDivider تعیین کردیم که بالای گروه اول خط نباشد و خط فقط بالای گروه دوم ما (موارد دیگر) قرار گیرد.
گزینه withSelectable تعیین میکند که با انتخاب هر آیتم، رنگ پسزمینه آن تغییر کند یا خیر که ما در این پروژه به این خاصیت نیاز ندارید و آن را غیرفعال کردیم.
به وسیله گزینه withIdentifier هم به آیتم یک id دادیم و بهوسیله آن میتوانید بعدا به آن آیتم دسترسی داشته باشیم. (مثل دسترسی و حذف این آیتم در آینده)
در اینجا منوی ما شکل ظاهری خود را گرفت اما با تپ کردن روی هرکدام اتفاقی نمیافتد و باید برای آیتمهای منو وظیفه تعیین کنیم.
از کدهای زیر برای کنترل خاصیت onClick روی آیتمها استفاده میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { switch (position) { case 2: // Settings break; case 4: // Support app break; case 5: // Contact break; case 6: // About break; case 7: // Feedback break; case 8: // Purchase break; default: break; } return true; } }) |
با Switch روی Position آیتمها مشخص میکنیم که هر آیتم به کدام اکتیویتی متصل شود.
و در نهایت شکل کلی کدهای Navigation Drawer ما به این صورت خواهد بود:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
drawer = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) .withDrawerGravity(drawerGravity) .withShowDrawerOnFirstLaunch(true) .addDrawerItems( new SectionDrawerItem().withName("دفترچه").withTextColor(ContextCompat.getColor(this, R.color.md_grey_500)).withDivider(false), new SecondaryDrawerItem().withName("تنظیمات").withIcon(R.drawable.ic_settings).withSelectable(false), new SectionDrawerItem().withName("موارد دیگر").withTextColor(ContextCompat.getColor(this, R.color.md_grey_500)), new SecondaryDrawerItem().withName("حمایت از برنامه").withIcon(R.drawable.ic_support).withSelectable(false), new SecondaryDrawerItem().withName("ارتباط").withIcon(R.drawable.ic_contact).withSelectable(false), new SecondaryDrawerItem().withName("درباره").withIcon(R.drawable.ic_about).withSelectable(false), new SecondaryDrawerItem().withName("بازخورد").withIcon(R.drawable.ic_feedback).withSelectable(false), new SecondaryDrawerItem().withName("ارتقا به نسخه پیشرفته").withIcon(R.drawable.ic_purchase).withSelectable(false).withIdentifier(8) ) .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { switch (position) { case 2: // Settings break; case 4: // Support app break; case 5: // Contact break; case 6: // About break; case 7: // Feedback break; case 8: // Purchase break; default: break; } return true; } }) .build() |
کتابخانه MaterialDrawer قابلیتهای فراوانی دارد و ساخت منوی کشویی را راحت کرده است. در استفاده از کلاسهای این کتابخانه محدودیت وجود ندارد و شما میتوانید کلاسهای آن را extend کنید و به دلخواه به کار ببرید.
از قابلیتهای این کتابخانه ساپورت از api 10، راهاندازی سریع، کاربری آسان، ساپورت RTL، قابلیت Customize کردن فراوان و… است. با گشت و گذار در مستندات آن در گیتهاب میتوانید بیشتر در مورد آن یاد بگیرید.
موفق باشید.
سلام خسته نباشید
من از این کتاخونه می خوام استفاده کنم ولی به پروژه ایمپورت نمیشه ارور میده
چه پیغامی میده؟
سلام. ممنون بابت مطالب خوب و مفیدتون… منتظر پست های بعدیتون هستیم بی صبرانه فقط لطفا فاصله ی زمانی رو بین فصل ها کمتر کنید. بازم ممنون
اگه میشه از فرگمنت ها و دیتابیس مطلب بذارید
سلام. ممنون. سعی میکنم فاصله بین پستها کمتر باشه. موضوعهایی که فرمودید هم درنظر میگیرم.
سلام
چطور میشه مثل عکسی که گذاشتید به بالای منوی کشویی، اون قسمت هدر رو اضافه کرد
منظورم اون عکس متریال و عکس پروفایل و… هستش
سلام. در مستندات کتابخانه که لینکشو گذاشتم به دنبال AccountHeader بگردید.
سلام من drawer خود اندروید استدوی استفاده کردم (موقعه ساخت اکتیوتی اکتیوتی داری drawer رو انتخاب کردم) اونو هم میشه برد سمت راست یا نه نمیشه؟
سلام من موقع ایمپورت این ارور میده
Error:(2, 0) Plugin with id ‘com.novoda.bintray-release’ not found.
سلام ممنون از اموزش بنده مشکلی داشتم اینه که این titlebar میاد روی drawer کلا انگار اومده پایین بعد از اضافه کردن کتابخونه روی صفحه اصلیم گرفته
http://8pic.ir/images/jjashhwvpfpmtkx28v19.png
من نفهمیدم این کد رو کجا باید وارد کنم؟
.withToolbar(toolbar)
کاشکی آخر هر آموزش سورسش هم بزارید
یا کد نهایی رو
سلام با عرض سلام و خدا قوت
ضمن تشکر از مطالب خوبتون استفاده کردم
بی صبرانه منتظر پست های بعدی تون هستم ….
سید علی حسینی