برنامههایی که از Drawer استفاده میکنند زیاد هستن و اکثرا این منوی پرکاربرد رو در سمت چپ برنامه قرار دادن (برنامههای فارسی البته) که از چپ به راست باز میشه. مدتی قبل به دنبال یک کتابخونه خوب با پشتیبانی از RTL میگشتم که اتفاقی این کتابخونه رو پیدا کردم.
چندتا از ویژگیهاش رو میگم:
- بهراحتی با هر پروژهای که دارید در مدت زمان خیلی کم integrate میشه.
- از اندروید ورژن ۱۰ به بالا پشتیبانی میکنه.
- امکان معرفی چندین پروفایل کاربری مثل برنامه جیمیل رو داره.
- و از همه مهمتر اینکه به راحتی راست به چپ یا اصطلاحا RTL میشه.
مراحل کار و سورس برنامه رو در Github به همراه تمامی commitهایی که انجام شده قرار دادم. هر گونه pull request در جهت بهبود برنامه پذیرفته میشود 🙂
قبل از هر چیز با استفاده از Android Studio یک پروژه جدید با یک activity از نوع empty ایجاد میکنیم:
وقتی که پروژه ایجاد شد و کار gradle تموم شد، برنامه رو اجرا کنید تا خروجی برنامه رو ببینید:
ابتدا خطوط زیر رو به gradle.build برنامه اضافه میکنیم:
compile 'com.android.support:design:23.1.1' compile('com.mikepenz:materialdrawer:4.5.8@aar') { transitive = true } compile 'com.mikepenz:google-material-typeface:2.2.0.1@aar' compile 'com.mikepenz:fontawesome-typeface:4.4.0.1@aar'
منتظر باشید تا کار sync کتابخونهها تموم بشه.
بعدش به کلاس MainActivity دو متغییر زیر رو اضافه میکنیم:
private AccountHeader headerResult = null; private Drawer result = null;
اولین متغییر برای تعریف حساب کاربری و هدر Drawer و دومی هم برای تعریف لیست منو مورد استفاده قرار میگیره. در ادامه مقدار دهی و تنظیمات هر کدوم توضیح داده میشه.
برای استفاده از قالبهای ارائهشده توسط این کتابخانه فایل activity_main.xml رو به صورت زیر ویرایش کنید:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="ir.bkhezr.materialdrawerrtl.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> </android.support.design.widget.CoordinatorLayout>
با این تغییر میتوان به toolbar برنامه دسترسی پیدا کرد و مقادیرش رو به دلخواه تغییر داد. نکته دیگه مربوط به styleهای استفاده شده هست، این استایلها در فایل styles.xml به صورت زیر تعریف شدهاند:
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
هدف از این تغییرات استفاده از برنامه به صورت تمامصفحه هست که در تنظیمات المان CoordinatorLayout به صورت android:fitsSystemWindows=”true” مشخص شده.
سپس به MainActivity کد زیر رو برای دسترسی به toolbar اضافه میکنیم:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);
برای اعمال استایل کتابخونه به فایل AndroidManifest.xml خط زیر را در بخش MainActivity اضافه میکنیم:
android:theme="@style/MaterialDrawerTheme.Light.DarkToolbar"
حالا نوبت به مقداردهی هدر و لیست میرسه، ابتدا یک پروفایل با مشخصات زیر ایجاد میکنیم:
IProfile profile = new ProfileDrawerItem().withName("Behrouz Khezry").withEmail("bkhezry@gmail.com").withIcon(R.drawable.profile);
سپس کدهای زیر رو اضافه میکنیم:
headerResult = new AccountHeaderBuilder() .withActivity(this) .withCompactStyle(true) .addProfiles( profile, new ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new Gmail Account").withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_dark_primary_text)).withIdentifier(1), new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings) ) .withSavedInstance(savedInstanceState) .withTextColor(Color.BLACK) .build(); result = new DrawerBuilder() .withActivity(this) .withAccountHeader(headerResult) //set the AccountHeader we created earlier for the header .addDrawerItems( new PrimaryDrawerItem().withName("Home").withIcon(FontAwesome.Icon.faw_home).withIdentifier(1), new PrimaryDrawerItem().withName("Free Play").withIcon(FontAwesome.Icon.faw_gamepad), new PrimaryDrawerItem().withName("Custom").withIcon(FontAwesome.Icon.faw_eye), new SectionDrawerItem().withName("Section Header"), new SecondaryDrawerItem().withName("Settings").withIcon(FontAwesome.Icon.faw_cog), new SecondaryDrawerItem().withName("Help").withIcon(FontAwesome.Icon.faw_question).withEnabled(false), new SecondaryDrawerItem().withName("Source").withIcon(FontAwesome.Icon.faw_github), new SecondaryDrawerItem().withName("Contact").withIcon(FontAwesome.Icon.faw_bullhorn) ) .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { if (drawerItem != null && drawerItem.getIdentifier() == 1) { } if (drawerItem instanceof Nameable) { toolbar.setTitle(((Nameable) drawerItem).getName().getText(MainActivity.this)); } return false; } }) .withSavedInstance(savedInstanceState) .withDrawerGravity(Gravity.END) .build();
دقت کنید که با تغییر Gravity.END منو از سمت راست باز میشه با تغییر این مقدار به Gravity.START منو از سمت چپ باز خواهد شد.
تقریبا برنامهمون آمادهست، برنامه رو اجرا میکنیم و خروجی برنامه به صورت زیر هست:
اگه دقت کنید متن toolbar به سمت راست نیومده و هنوز سمت چپ هست برای جابجا کردنش به سمت راست، من خودم یه ایده دادم شاید روش بهتر و سادهتری وجود داشته باشه، اگه هست توی کامنت بهم بگید، ممنون میشم.
من از menu استفاده کردم، ابتدا فایل menu_main.xml رو ایجاد میکنیم و کد زیر رو داخلش وارد میکنیم:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="ir.bkhezry.materialdrawerrtl.MainActivity"> <item android:id="@+id/title" android:orderInCategory="100" android:title="MaterialDrawer" app:showAsAction="always" /> <item android:id="@+id/drawershow" android:orderInCategory="100" android:title="" android:icon="@mipmap/ic_view_headline_white_48dp" app:showAsAction="always" /> </menu>
با این کار یک عکس و یک متن به ActionBar اضافه میشه. از عکس برای باز کردن Drawer و از متن برای نمایش عنوان برنامه استفاده میکنیم. دقت کنید که باید عنوان اصلی toolbar رو هم به صورت خالی در نظر بگیریم:
toolbar.setTitle(""); ... @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.drawershow) { result.openDrawer(); return true; } return super.onOptionsItemSelected(item); }
برنامه رو اجرا میکنیم، خروجی برنامه به صورت زیر هست:
حتما به لینک اصلی کتابخونه مراجعه کنید، توضیحات خیلی بیشتری ارائه شده، همچنین اگه به بخش issue مراجعه کنید متوجه خواهید شد که ارائهدهنده این کتابخونه هیچ سوالی رو بیجواب نگذاشته.
ببخشید ولی DrawerLayout که توی ساپورت لایبرری ۴ گنجانده شده و به راحتی راست به چپ میشه دیگه نیازی به استفاده از لایبرری های دیگه نیست.
بله حرف شما درسته.
این کتابخانه چیزی بیشتر از راست به چپ کردن داره والا چهار هزار ستاره نمیگرفت.
مثل این میمونه بگیم که وقتی جاوا اسکریپت همه چیز داره، چه نیازی به جی کوئری هست.
بسیار عالی و کاربردی مثله همیشه Top 🙂
خیلی جالبه مطالب شما همش تخصصی هستند و کسی جز برنامه نویسان متوجه نمیشوند. این خیلی روند خوبیه و امیدوارم همه وبلاگ های ایران تخصصی بشوند.
فوق العاده بووووووود:-*
سلام دوستان
من برای ساخت منوی کشویی از این روش استفاده کردم . روش بسیار راحت و ساده ای است اما برای تغییر سایز و رنگ دادن به آیکون ها ( در حالت پیش فرض آیکون ها خاکستری نمایش داده می شوند حتی اگر رنگی باشند) با مشکل مواجه شدم که البته با سرچ زیاد حل شد.
مشکل الان اینجاست که چطور فونت های استفاده شده را به فونت دلخواه تغییر دهم؟؟؟؟؟
سلام وقت بخیر، برای تغییر فونت برنامه به این آدرس که مقاله ای دیگر از سایت هست مراجعه کنید:
http://goo.gl/wcB77w
سلام. ممنون از راهنمایی تون . ولی من همون مرحله ی اول گیر کردم. موقع اضافه کردن کتابخونه به اندروید استودیو با خطا مواجه میشم. شاید باید وی پی ان استفاده کنم؟ درسته؟
چند روزه که پورت ۴۴۳ با کندی سرعت و بعضا با قطعی مواجه هست، بله استفاده کنید 🙂
ممنون بهروز جان
سلام . میخواستم بدونم چطور میشه عناصر روی دراورو به این روش روی کل دراور ست کرد؟ مثلا من پنج تا گزینه داره لیستم و توی گوشی ۴٫۷ اینچ تا پایین منو پر میشه ولی روی گوشی ۵ اینچ فضای پایین خالی می مونه که اصلا جالب نیست. ممنون میشم راهنمایی کنین
در این مورد ایدهای ندارم
توو بخش issue کتابخانه هم گشتم و چیزی پیدا نکردم.
به فرض اندازه در ۵ اینچ کاملا fit بشه
برای سایزهای کوچکتر یعنی همین ۴٫۷ باید اسکرول کنید تا همه آیتمها رو ببینید
به نظرم کلا روش درستی نیست این کار.
سلام ممنونم بابت آموزش خوبتون
ی خواهشی داشتم می خوام از datepiker بصورت فارسی ( شمسی) که امکان انتخاب تاریخ توسط کاربر رو داشته باشه توی برنامه استفاده کنم ی کتابخونه پیدا کردم اما هر کاری می کنم خطا میده امکانش هست مثل کاری برای منو انجام از این کتابخونه یاستفاده کنید و ی آموزشی بدید ؟
خیلی ممنون میشم https://github.com/alirezaafkar/SunDatePicker
سلام،
این کتابخانه رو تست کردم و خطایی نداشت.
سلام امکانش هست ی مثال عملی بزنید من هر کاری می کنم با مشکل برخورد می کنم ؟؟؟؟
ممنون میشم
سلام،
متن مقاله رو مجددا بخونید، ذکر شده که سورس کامل این مثال در گیت هاب قرار گرفته.
سلام و خسته نباشید به جناب خضری
بنده نمونه رو از گیتهاب گرفتم و اجرا کردم چند مورد :
اگر زبان گوشی انگلیسی باشه برنامه درست کار میکنه ولی اگر زبان گوشی فارسی باشه جواب نمیده!!
یعنی خود اندروید طبق زبان گوشی تغییر اعمال میکنه!
که نمونه دراوری که خود اندروید استودیو گذاشته تو زبان فارسی راست به چپ و انگلیسی چپ به راست میاره !
چطور میشه در دو حالت (زبان گوشی هر زبانی که باشه ) راست به چپ بیاره ؟؟؟؟
سلام،
من تا الان روی گوشی با زبان فارسی تست نکردم. دو پیشنهاد دارم
اول اینکه locale برنامه رو در برنامهنویسی تغییر بدید
http://stackoverflow.com/questions/2900023/change-language-programatically-in-android
دوم اینکه در بخش issue این کتابخانه گفته شده که برای راست به چپ بودن، باید در Android manifest گزینه rtl رو اضافه کنید که به حداقل نسخه اندروید ۱۴ نیاز داره. بگردید در اون بخش پیداش میکنید، اگه مشکل رو حل کردن، همینجا اطلاع بدید.
ممنون.
شما میتونید از طریق کد زیر شرط تعیین زمانی که صفحه گوشی چپ به راست یا بالعکس باشه اینکارو براتون انجام بده.
Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
}else{
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
خیلی ممنونم بابت راهنمایتون
با روش اول جواب گرفتم ، منتهی :
زبان رو نباید رو فارسی گذاشت؛
من زبان رو به انگلیسی ست کردم درست شد!
———————————————-
احتمالا کتابخانه فقط در حالت انگیسی بودن دیوایس راست به چپ میکنه!
حل شد ولی نمیدونم اصولیه یا نه!
لطفا اگه اصولی نیست – راه های دیگه ای هست مطرح کنید ممنون میشم.
چون کانفیگ کردن به انگلیسی اپ نمیدونم شاید در آینده مشکل ساز بشه!
شایدم نشه!
ولی باز بهتره از اصولی بودن کار خیالمون راحت بشه خوبه!
بر روی گوشی اس سه سامسونگ که فارسی بود تستش کردم،
در هر دو حالت فارسی و انگلیسی از سمت راست باز شد. شاید برای اون دستگاه خاص مشکل داره، پیشنهاد میکنم روش دوم رو هم امتحان کنید
خیلی ممنون گوشی من هواوی y511 – anroid 4.2.2 – احتمالا همینطوریه که شما میفرمایید!
نمونه دوم رو رفتم تو پیج گیتهابش – نتونستم چیزی در این مورد پیدا کنم.
اگه بیشتر راهنمایی کنین ممنون میشم!
یه rtl جستجو میکردید کلی راهنمایی و سوال وجود داره
https://github.com/mikepenz/MaterialDrawer/issues/1044
جناب خضری ممنون برای پاسخ هاتون
زیاد وقتتون رو گرفتم – همون روش اول رو اجرا میکنم
————
خیلی لطف کردین !
آموزشهاتون و نکاتتون حرف ندارن!
———–
چطوری میشه nav drawer زیر Toolbar باز بشه ؟
سلام،
به لینک زیر برید و دمو این کتابخانه رو نگاه کنید، مثالش ذکر شده
https://github.com/mikepenz/MaterialDrawer
سلام و خسته نباشید
دو تا سوال دارم اول اینکه ایتم های درون drawer رو چه جوری میشه راست چین کرد و دوم اینکه چه جوری رنگ drawer رو مانند مثال هاش میشه تیره کرد
سلام،
برای سوالتون بهتره به بخش issue کتابخانه در گیتهاب مراجعه کنید. مثالهاش رو بررسی کنید، تنظیمات بیشتری داره.
بخصوص در نسخه جدید.
https://goo.gl/dSO1sl
سلام ، ممنونم بابت انتنشار این پست و معرفی این کتابخانه . از گیتهاب گرفتمش و دارم راست به چپش رو بررسی می کنم . باز هم تشکر از شما
با سلام، من وقتی که خطوط مربوط به کتابخانه mikepenz:materialdrawer را در قسمت gradle.bulid اضافه میکنم بعد از sync شدن برای هر سه کتابخانه با این خطا روبرو میشم
Failed to resolve: com.mikepenz:materialdrawer:4.5.8
چطور میتونم این مشکل را حل کنم و کتابخانه را به پروژه اضافه کنم
سلام. مشکل شما احتمالا بخاطر تحریم بودن jcenter هست.
متاسفانه برای سینک کردن کتابخانهها به ویپیان نیاز دارید.
با سلام مجدد، حتی با استفاده از vpn هم ، دوباره خطا میده ….
سلام
همین الان نسخه این آموزش و نسخه جدید کتابخانه رو تست کردم و با ویپیان اضافه شد.
سلام خسته نباشید چطوری میشه از این یه کلاس ساخت که مجبور نباشیم تو هر صفحه از اکتیوتی ها از این همه کد استفاده کنیم
کسی ایده ای نداره؟
http://goo.gl/re2G4y
بهروز جون عالیه (دلمم واست تنگ شده ;))
سلام من این کتابخانه رو تونستم پیاده سازی کنم اما چرا نمیشه تو لایوت main.xml تغییرات رو به خوبی انجام داد و تازه اگر هم مثلا یه باتن در بالاترین سطح قرار بدیم میره زیر Toolbar
سلام،
برای حل این مشکل از include کردن layout مانند این مثال درgist استفاده کنید:
https://gist.github.com/bkhezry/a638133716157411f61b5afc368a36e9
واقعا ممنونم.عالی بود.
سلام.
برای حالت Em,bedded که منو زیر toolbar باز بشه چکار باید بکنم؟
میخوام زیر تولبار باشه و drawertoggle هم موقعی که منو باز میشه به صورت فلش در بیاد
با سلام و خسته نباسید ممنونم از آموزش خوبتون
در همون ابتدا موقع اظافه کردن compile ها به فایل gradle.bield با خطا مواجه میشم ممنونم راهنمایی بفرمایید بدجوری گیر کردم :((((((((((
عکسش رو نتونستم اینجا آپلود کنم
سلام آموزش بسیار عالی بود فقط سوالی که برام بیش اومد میخواستم بدونم چطوری میشه به هر یک از ایتم های داخل منوی کشوییمون وظیفه داد یا به صورتی تعریفشون کرد مثل یک باتن
سلام.اقا این همون یه که من میخوام.ولس من با اکلیپس کار میکنم و gradle.build رو نداره.
خواهش میکنم کمکم کنید تا با اکلیپس درستش کنم.چیکار باید کنم.کتابخونه خاصی هم باید وارد کنم?
سلام ببخشید میخواستم بدونم چگونه میشه رنگ ایکون نویگیشت دراور رو داخل تولبار تغیر داد اگه میشه راهنمایی کنید؟؟؟؟؟
سلام
داخل تولبار با این خط به راحتی راست به چپ میشه نوشته و آیکون
android:layoutDirection=”rtl”
با سلام
این مبحث بین سری آموزش جاوا بین قسمت های ۶ و ۷ قرار گرفته که به نظر نامرتبط می رسهُ لطفا اصلاح شود.
تشکر