معماری تک اکتیویتی در navigation


معماری تک اکتیویتی

مدیریت جریان پیچیده ای از navigation با معماری تک اکتیویتی

انواع معماری ها برای مدیریت navigation یک برنامه، موضوعی بود که در مقاله های پیشین بلاگ بررسی کردیم. به طور خاص مزایا و معایب معماری تک اکتیویتی را بررسی نمودیم. در این مقاله قصد داریم تا معماری تک اکتیوتی برای مدیریت flow یک برنامه که درگیر navigaion و قسمت های مختلف می باشد، را در غالب مثالی تشریح کنیم.

فرض کنید برنامه ی مورد نظر یک سیستم برای ورود و اعتبارسنجی کاربران دارد. پس از رد کردن این مرحله و ورود کاربر به برنامه، بر اساس نوع عضویت به flow متفاوتی از برنامه هدایت می شوند. بدون navigation component، باید تعداد زیادی اکتیویتی بسازیم که ممکن است شامل فرگمنت باشند یا نباشند. در این لحظه ممکن است سوالی برای شما پیش بیاید.

آیا تنها یک اکتیویتی می تواند کافی باشد؟

در واقع نحوه تعریف گراف navigation در پوشه resources برنامه کلید پاسخ این سوال است. گراف navigation شامل تمام مقصدهای برنامه و اعمالی ست که بناست در برنامه اجرا شوند. طراحی یک گراف تو در تو برای navigation می تواند flow یا جریان برنامه را از طریق یک اکتیویتی مدیریت کند.

تعریف گراف navigation

فرض کنید بدون تعریف این گراف بخواهیم برنامه را بسازیم. با انبوهی از کدها و تعداد زیادی اکتیوتی (اعتبارسنجی، جریان 1 برای کاربر نوع 1، جریان2 برای کاربر نوع 2) رو به رو خواهیم بود. که بدیهی ست تمیز به نظر نخواهد آمد. در همین هنگام است که معماری تک اکتیویتی به کمک برنامه می آید. برای طراحی یک گراف تو در تو، ابتدا گراف کلی برنامه را می سازیم. و جریان های دیگر برنامه که زیر مجموعه جریان اصلی محسوب می شوند را در گراف navigation جداگانه می نویسیم.

معماری تک اکتیویتی

در نهایت با 4 گراف رو به رو هستیم. در تنها اکتیوتی برنامه، NavHostFragment به کمک @navigation/main_navigation تنظیم گردیده است. که در واقع همین مورد گراف اصلی برنامه است. سپس 3 فرگمنت دیگر شبیه به همین گراف به نظر می رسند.

<?xml version="1.0" encoding="utf-8"?>
  <navigation 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:id="@+id/main_navigation"
      app:startDestination="@id/authenticationFragment">
  

      <fragment
          android:id="@+id/authenticationFragment"
          android:name="com.awesomeapp.android.authentication.AuthenticationFragment"
          android:label=""
          tools:layout="@layout/authentication_fragment">
          <action
              android:id="@+id/action_authenticationFragment_to_flow1Fragment"
              app:destination="@id/flow1Fragment"
              app:launchSingleTop="true"
              app:popUpTo="@+id/main_navigation"
              app:popUpToInclusive="true" />
          <action
              android:id="@+id/action_authenticationFragment_to_flow2Fragment"
              app:destination="@id/flow2Fragment"
              app:launchSingleTop="true"
              app:popUpTo="@+id/main_navigation"
              app:popUpToInclusive="true" />
      </fragment>
  

      <fragment
          android:id="@+id/flow1Fragment"
          android:name="com.awesomeapp.android.main.Flow1Fragment"
          android:label=""
          tools:layout="@layout/flow1_fragment" />
  

      <fragment
          android:id="@+id/flow2Fragment"
          android:name="com.awesomeapp.android.main.Flow2Fragment"
          android:label=""
          tools:layout="@layout/flow2_fragment" />

Navigate یا هدایت برنامه میان گراف ها

هدایت یا navigate برنامه به مقصدی خاص به کمک عنصر NavController انجام می شود. در واقع هر NavHostFragment با گراف مربوط به خود به کمک NavController برنامه را به بخش های مختلف آن هدایت می نماید. برای نام گذاری نام اکیتویتی یا فرگمنت را به NavController وصل می کند.

معماری تک اکتیویتی

همانطور که مشاهده می کنید در این برنامه 4 NavController وجود دارد. در لایه مربوط به اکتیویتی، mainNavController را داریم. در لایه فرگمنت ها، سه navController با نام های authenticationNavControllerflow1NavController,  و flow2NavController  را داریم.

برای روشن تر شدن موضوع مثال دیگری را در نظر می گیریم. تا چگونگی هدایت برنامه بین این اکتیویتی ها و فرگمنت ها را درک کنیم. فرض کنید یک صفحه login داریم که مربوط به گراف navigation برای بخش اعتبارسنجی برنامه ست. شبیه به تصویر زیر:

معماری تک اکتیویتی

این صفحه باید بتواند به دیگر صفحه های  بخش اعتبارسنجی هدایت گردد. فرضا صفحه هایی مثل فراموشی رمز عبور، فعال سازی کاربر. هم چنین باید بتواند به flow1 یا flow2 پس از ورود موفق کاربر به برنامه هدایت شوند. تصویر زیر را مشاهده کنید.

معماری تک اکتیویتی

برای ساخت این navigation نیاز به ساخت نمونه از authenticationNavController و mainNavController داریم. در همین قسمت مزیت استفاده از معماری تک اکتیوتی را دیده می شود.

به فرگمنت مربوط به login کاربر توجه کنید :

class LoginFragment : BaseLifeCycleFragment() {
  

      override val viewModel by viewModel<LoginViewModel>()
  

      val mainNavController: NavController? by lazy { activity?.findNavController(R.id.main_nav_host_fragment) }
  

      val authentionNavController: NavController? by lazy { view?.findNavController() }
  

      ...
    
      override fun onActivityCreated(savedInstanceState: Bundle?) {
          super.onActivityCreated(savedInstanceState)
           with(viewModel) {
              _navigateToFlow1.observe(viewLifecycleOwner, Observer {
                  val direction = AuthenticationFragmentDirections.actionAuthenticationFragmentToFlow1Fragment()
                  mainNavController?.navigate(direction)
              })
  

              _navigateToFlow2.observe(viewLifecycleOwner, Observer {
                  val direction = AuthenticationFragmentDirections.actionAuthenticationFragmentToFlow2Fragment()
                  mainNavController?.navigate(direction)
              })
          }
      }
    
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
  

          signUpBtn.setOnClickListener {
              val direction = LoginFragmentDirections.actionLoginFragmentToSignUpFragment()
              authentionNavController?.navigate(direction)
  

          }
          forgotPasswordBtn.setOnClickListener {
              val direction = LoginFragmentDirections.actionLoginFragmentToForgotPasswordFragment()
              authentionNavController?.navigate(direction)
          }
        
          ...
      }
  }

همانطور که مشاهده می کنید در loginFragment دو نمونه از authenticationNavController و mainNavController ساخته شده است. mainNavController می تواند نمونه ای از اکتیویتی باشد و به منظور هدایت برنامه به فرگمنتی خارج از @navigation/authentication_navigation استفاده می شود. با نمونه از فرگمنت authenticationNavController  می توان به دو جریان دیگر برنامه رسید.

مزیت اصلی معماری تک اکتیویتی این است که اهمیتی ندارد در کدام فرگمنت قرار دارید، یا چقدر در فرگمنت های تو در توی برنامه قرار گرفته اید. همیشه می توان نمونه ای از mainNavController مربوط به تنها اکتیویتی برنامه ساخت و آنرا با بخش های مختلف برنامه به اشتراک گذاشت. تا به flow های مختلف برنامه از این طریق پیوست.

نتیجه گیری

با به کار گیری مفهومی که بررسی شد، برخی از پیچیدگی های سناریوی استفاده از navigation که احتمال دارد با آنها برخورد کنید توضیح داده شد.

فرگمنت ها هم می توانند به NavContoroller لایه اکتیویتی (activity-level) و هم NavContoroller لایه ویوها (view-level) دسترسی داشته باشند. نیازی نیست فرگمنت برای این دسترسی، این نکته که کدام navigationهای فرگمنت در لایه های بیرونی تر قرار دارند را در نظر بگیرند. کافی ست NavController مربوط به خود را داشته باشد.

به این پست امتیاز دهید

روی ستاره های کلیک کنید و امتیاز بدید

میانگین امتیاز / 5. تعداد:

دیدگاهتان را بنویسید

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




Enter Captcha Here : *

Reload Image