رویکرد جدید؛ یک اکتیویتی برای هر اپلیکیشن کافیه! (۲)

این نوشته دومین و آخرین بخش از آموزش ابزار Navigation Component در برنامه‌نویسی اندروید هست، اگر با این ابزار آشنایی ندارید پیشنهاد می‌کنم قبل از خواندن این متن، نوشته رویکرد جدید؛ یک اکتیویتی برای هر اپلیکیشین کافیه (1) رو مطالعه کنید.در بخش اول این آموزش در مورد اینکه ابزار Navigation چیه و چطوری کار می‌کنه حرف زدیم، در این نوشته به پیاده‌سازی دو مورد کاربردی دیگه در کار با Navigation می‌پردازیم:انتقال داده در هنگام جابجایی با استفاده از پلاگین Safe Argsپیاده‌سازی طرح‌‌های پیچیده‌تر با استفاده از کلاس کمکی NavigationUI (طرح‌هایی مثل BottomNavigationView، NavigationDrawer و غیره )لینک مثال‌های این نوشته در گیت‌هاب: انتقال داده با استفاده از پلاگین SafeArgs https://github.com/itsamirrezah/SimpleNavigationComponent/tree/Navigation-SafeArgs ۲. پیاده‌سازی BottomNavigationView با استفاده از Navigation https://github.com/itsamirrezah/SimpleNavigationComponent/tree/Navigation-BottomNavigationView انتقال داده بین Destination هایکی دیگه از ویژگی‌های Navigation، انتقال داده در زمان جابجایی بین Destination ها است. روش کار به این صورت که آرگومانی که می‌خواهیم از یک صفحه به صفحه بعدی ارسال بشه رو باید در فایل گراف مسیریابی معرفی کنیم. برای این‌کار از تگ <argument> استفاده می‌کنیم تا در فایل گراف مسیریابی نوع داده، مقدار پیشفرض و نام متغیرمون رو مشخص کنیم. <argument> باید درون تگ Destination مقصد معرفی بشه.اضافه کردن argument به صفحه Destination مقصدتغییرات در محیط Designاضافه کردن argument به Destination مقصدتغییرات در محیط Text https://gist.github.com/itsamirrezah/d36579003f32945cfb9d439805d585c4 ویژگی‌های مهم argument:android:nameیک نام منحصر به فرد برای آرگومان انتخاب می‌کنیم تا بعدا با استفاده از این نام به مقدار اون دسترسی پیدا کنیم.app:argTypeنوع داده‌ای متغیرandroid:defaultValueمقدار پیشفرض متغیرلیستی از انواع تایپ‌های داده‌ای که Navigation اون‌ها رو پشتیبانی می‌کنه: لینکخب حالا می‌رسیم به قسمت اصلی کار، یعنی ارسال داده‌ها. تاحالا هیچ داده‌ای ارسال نکردیم فقط یک سری سیاست در گراف مسیریابی مشخص کردیم و گفتیم قراره از این صفحه به فلان صفحه، داده‌ هایی با این ویژگی‌ها ارسال بشه.برای ارسال و دریافت مقادیر بین صفحات باید از پلاگین Safe Args استفاده کنیم. این پلاگین برای دسترسی امن به آرگومان‌های گراف مسیریابی طراحی شده و روش کارش هم به این صورت که براساس آرگومان‌های ارسال شده، ‌Destination‌ های مبدا و مقصد یک مجموعه کلاس به صورت اتوماتیک تولید می‌کنه و کاربر با استفاده از این کلاس‌ها می‌تونه مقادیر رو برای ارسال در صفحه مبدا مشخص کنه یا در مقصد اون‌ها رو دریافت کنه.اضافه کردن Safe Args به پروژه:۱. تغییرات در فایل ریشه (top-level) build.gradle: https://gist.github.com/itsamirrezah/c578d9039da0b3b8fda9b6462b33f593 ۲. فعال سازی پلاگین در فایلbuild.gradle(app): https://gist.github.com/itsamirrezah/195fe43d87937887d967ae2041cb535a گفتیم روش کار Safe Args به این صورت‌ که یه سری کلاس، متد و فیلد رو براساس سیاست‌های گراف مسیریابی تولید می‌کنه. حالا می‌خواهیم کمی بیشتر وارد جزئیات این کار بشیم. به طور کلی Safe Args براساس سه پارامتر مهم (در گراف مسیریابی)‌کلاس یا متد تولید می‌کنه. Destination مبدا، Destination مقصد و Action مرتبط.برای هر Destination مبدا یک کلاس تولید میشه که دقیقا با نام خود Destination شروع میشه و با کلمه «Directions» به اتمام می‌رسه. به عنوان مثال اگه نام Destination مبدا شما FragmentA باشه، Safe Args یک کلاس با نام FragmentADirectionsتولید می‌کنه.برای هر action ( اکشنی که Destination مبدا رو به مقصد متصل می‌کنه!) یک کلاس داخلی (Inner class) درون کلاس «…Directions» تولید میشه. اسم این کلاس هم تقریباً شبیه به آیدی تگ <action> در گراف مسیریابی است. مثلا اگه آیدی <action> استفاده شده:‌ navigate_to_fragb باشه کلاسی با نام NavigateToFragb تولید میشه. بعلاوه در کلاس «…Direction» هم یک متد هم‌نام کلاس action تولید میشه که وظیفه این متد اینه که از کلاس action یک نمونه (instance) ایجاد کنه.برای هر Destination مقصد یک کلاس جدید تولید میشه که با نام اصلی Destination مقصد شروع میشه و با کلمه «Args» به اتمام می‌رسه. به عنوان مثال اگر نام Destination مقصد شما FragmentB باشه یک کلاس با نام FragmentBArgs تولید میشه.مثال؛ انتقال داده از FragA به FragB:۱. ارسال مقدار آرگومان در Destination مبدا: https://gist.github.com/itsamirrezah/c58f333dd6b3a60674a26bbe8c7a999e با استفاده از دستور ()FragADirections.actionNavigateToFragmentB یک نمونه از کلاس ActionNavigateToFragmentB می‌سازیم و از این طریق به تگ <action> ای که در گراف مسیریابی ساختیم دسترسی پیدا می‌کنیم. در آخر هم از شی NavController استفاده‌ می‌کنیم تا عملیات انتقال رو نهایی کنیم.۲. دریافت مقدار ارسال‌ شده در Destination مقصد https://gist.github.com/itsamirrezah/baa4c12d54b8bc16afa11c0344ef64ae دریافت داده از ارسال اون هم ساده تره، فقط باید از کلاس FragmentBArgs و یک Bundle استفاده کنید تا به مقدار ارسال شده دسترسی پیدا کنید.انتقال داده با استفاده از Navigation و پلاگین SafeArgsعلاوه بر مثال‌هایی که در این دو نوشته دیدیم Navigation قادر به پیاده‌سازی ویو‌های پیچیده‌تری هم هست. ویوهایی مثل BottomNavgationView، NavigationDrawer، CollapsingToolbarLayout و .. . Navigation برای پیاده‌سازی این‌ ویو‌ها از کلاس کمکی NavigationUI استفاده ‌می‌کنه. در بخش انتهایی این مقاله می‌خواهیم یک نمونه از پیاده‌سازی چنین طرح‌هایی رو با استفاده از NavigationUI ببینیم.پیاده سازی BottomNavigationView با استفاده از Navigationلیستی از مواردی که برای این پیاده‌سازی نیاز داریم:۱. یک Activity که نقطه شروع برنامه است و در layout این اکتیویتی NavHost و BottomNavigationView رو قرار داده می‌شود. https://gist.github.com/itsamirrezah/570873f6aa9fd3aa3b2bd7b3293d46c7 ۲. معرفی چند فرگمنت به گراف مسیریابی به عنوان Destination ها۳. طراحی یک menu برای استفاده در BottomNavigationViewنکته مهم: توجه کنید‌ آیدی هر Item در این menu حتما با آیدی Destination مرتبط با خودش یکسان باشد! https://gist.github.com/itsamirrezah/3243bc1988599ada746bcf4efe38b7bc ۴. دسترسی به شی NavController در اکتویتی۵. و در‌نهایت برقراری اتصال بین BottomNavigationView و NavController ا۲.https://gist.github.com/itsamirrezah/cab0ce57cf0061f5661111d8a93580b4 همونطوری که در تکه‌ کد بالا مشخصه برای اتصال BottomNavigationView به NavController از کلاس جانبی NavigationUI استفاده می‌کنیم. NavigationUI کمک می‌کنه تا ویو‌هایی مثل NavigationDrawer، BottomNavigationView و .. رو به سادگی پیاده کنیم.با استفاده از متد setupWithNavController() امکان اتصال BottomNavigationView به NavController فراهم میشه. روش کارش هم به این صورتِ که بعد از اتصال، NavigationUI همیشه در حال گوش دادن به رویداد OnNavigationItemSelected() می‌مونه (این رویداد وقتی اجرا میشه که کاربر یکی از آیتم‌های BottomNavigationView رو انتخاب/لمس کنه)، هر زمانی که این رویداد اجرا شه NavigationUI آیدی MenuItem ای که کاربر روی اون لمس کرده رو دریافت می‌کنه و با استفاده از شی NavController صفحه مرتبط با آیتم انتخاب شده رو به کاربر نمایش میده. به همین خاطر که باید آیدی MenuItem ها با آیدی Destination ها یکسان باشند.پیاده‌سازی BottomNavigationView با استفاده از Navigationدر جمع بندی باید بگم Navigation ابزار بسیار ساده و در عین حال قدرتمندیه که اجازه دستیابی به رویکرد Single Activity Per Application رو به برنامه نویسان اندروید میده. پس اگر به این رویکرد علاقه‌مند هستید، پیشنهاد می‌کنم از این ابزارغافل نشید.امیدوارم این مجموعه آموزش‌ها برای شما مفید بوده باشه. اگه سوال، انتقاد یا پیشنهادی دارید می‌تونید یا زیر همین پست مطرح کنید یا از طریق توئیتر و تلگرام با من در تماس باشید. (: