মাল্টি-মডিউল প্রকল্পের জন্য নেভিগেশন সেরা অনুশীলন

একটি নেভিগেশন গ্রাফ নিম্নলিখিত যে কোনো সমন্বয় গঠিত হতে পারে:

  • একটি একক গন্তব্য, যেমন একটি <fragment> গন্তব্য।
  • একটি নেস্টেড গ্রাফ যা সম্পর্কিত গন্তব্যগুলির একটি সেটকে অন্তর্ভুক্ত করে।
  • একটি <include> উপাদান, যা আপনাকে অন্য একটি নেভিগেশন গ্রাফ ফাইল এম্বেড করতে দেয় যেন এটি নেস্ট করা ছিল।

এই নমনীয়তা আপনাকে আপনার অ্যাপের সম্পূর্ণ নেভিগেশন গ্রাফ তৈরি করতে ছোট নেভিগেশন গ্রাফগুলিকে একত্রিত করতে দেয়, এমনকি যদি সেই ছোট নেভিগেশন গ্রাফগুলি আলাদা মডিউল দ্বারা সরবরাহ করা হয়।

এই বিষয়ের উদাহরণগুলির জন্য, প্রতিটি বৈশিষ্ট্য মডিউল একটি বৈশিষ্ট্যের চারপাশে ফোকাস করে এবং একটি একক নেভিগেশন গ্রাফ প্রদান করে যা সেই বৈশিষ্ট্যটি বাস্তবায়নের জন্য প্রয়োজনীয় সমস্ত গন্তব্যগুলিকে অন্তর্ভুক্ত করে৷ একটি প্রোডাকশন অ্যাপে, আপনার নিম্ন স্তরে অনেকগুলি সাবমডিউল থাকতে পারে যা এই উচ্চ-স্তরের বৈশিষ্ট্য মডিউলটির বাস্তবায়নের বিবরণ। এই বৈশিষ্ট্যগুলির প্রতিটি মডিউল আপনার app মডিউলে প্রত্যক্ষ বা পরোক্ষভাবে অন্তর্ভুক্ত করা হয়েছে৷ এই ডকটিতে ব্যবহৃত মাল্টি-মডিউল অ্যাপ্লিকেশনটির উদাহরণ নিম্নলিখিত কাঠামো রয়েছে:

একটি নমুনা মাল্টি-মডিউল অ্যাপ্লিকেশনের জন্য নির্ভরতা গ্রাফ
উদাহরণ অ্যাপের শুরুর গন্তব্য
চিত্র 1. অ্যাপ আর্কিটেকচার এবং উদাহরণ অ্যাপের জন্য গন্তব্য শুরু করুন।

প্রতিটি বৈশিষ্ট্য মডিউল হল একটি স্বয়ংসম্পূর্ণ ইউনিট যার নিজস্ব নেভিগেশন গ্রাফ এবং গন্তব্য রয়েছে। app মডিউল প্রতিটির উপর নির্ভর করে, তাদের build.gradle ফাইলে বাস্তবায়নের বিবরণ হিসেবে যোগ করে, যেমন দেখানো হয়েছে:

গ্রোভি

dependencies {
    ...
    implementation project(":feature:home")
    implementation project(":feature:favorites")
    implementation project(":feature:settings")

কোটলিন

dependencies {
    ...
    implementation(project(":feature:home"))
    implementation(project(":feature:favorites"))
    implementation(project(":feature:settings"))

app মডিউলের ভূমিকা

app মডিউল আপনার অ্যাপের সম্পূর্ণ গ্রাফ প্রদান এবং আপনার UI-তে NavHost যোগ করার জন্য দায়ী। app মডিউলের নেভিগেশন গ্রাফের মধ্যে, আপনি <include> ব্যবহার করে লাইব্রেরি গ্রাফগুলি উল্লেখ করতে পারেন। যদিও <include> ব্যবহার করা একটি নেস্টেড গ্রাফ ব্যবহার করার মতোই কার্যকরীভাবে একই, <include> অন্যান্য প্রকল্প মডিউল বা লাইব্রেরি প্রকল্প থেকে গ্রাফ সমর্থন করে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<?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/nav_graph"
    app:startDestination="@id/home_nav_graph">

    <include app:graph="@navigation/home_navigation" />
    <include app:graph="@navigation/favorites_navigation" />
    <include app:graph="@navigation/settings_navigation" />
</navigation>

একবার একটি লাইব্রেরি শীর্ষ-স্তরের নেভিগেশন গ্রাফে অন্তর্ভুক্ত হলে, আপনি প্রয়োজন অনুসারে লাইব্রেরি গ্রাফগুলিতে নেভিগেট করতে পারেন। উদাহরণস্বরূপ, আপনি আপনার নেভিগেশন গ্রাফের একটি খণ্ড থেকে সেটিংস গ্রাফে নেভিগেট করার জন্য একটি অ্যাকশন তৈরি করতে পারেন, যেমন দেখানো হয়েছে:

<?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/nav_graph"
    app:startDestination="@id/home_nav_graph">

    <include app:graph="@navigation/home_navigation" />
    <include app:graph="@navigation/favorites_navigation" />
    <include app:graph="@navigation/settings_navigation" />

    <fragment
        android:id="@+id/random_fragment"
        android:name="com.example.android.RandomFragment"
        android:label="@string/fragment_random" >
        <!-- Launch into Settings Navigation Graph -->
        <action
            android:id="@+id/action_random_fragment_to_settings_nav_graph"
            app:destination="@id/settings_nav_graph" />
    </fragment>
</navigation>

যখন একাধিক ফিচার মডিউলের গন্তব্যগুলির একটি সাধারণ সেট উল্লেখ করার প্রয়োজন হয়, যেমন একটি লগইন গ্রাফ, আপনার প্রতিটি বৈশিষ্ট্য মডিউলের নেভিগেশন গ্রাফে সেই সাধারণ গন্তব্যগুলি অন্তর্ভুক্ত করা উচিত নয় ৷ পরিবর্তে, আপনার app মডিউলের নেভিগেশন গ্রাফে সেই সাধারণ গন্তব্যগুলি যোগ করুন। প্রতিটি বৈশিষ্ট্য মডিউল তারপর সেই সাধারণ গন্তব্যগুলিতে নেভিগেট করতে বৈশিষ্ট্য মডিউল জুড়ে নেভিগেট করতে পারে।

পূর্ববর্তী উদাহরণে, কর্মটি @id/settings_nav_graph এর একটি নেভিগেশন গন্তব্য নির্দিষ্ট করে। এই আইডিটি এমন একটি গন্তব্যকে নির্দেশ করে যা অন্তর্ভুক্ত গ্রাফ @navigation/settings_navigation.

অ্যাপ মডিউলে শীর্ষ-স্তরের নেভিগেশন

নেভিগেশন উপাদান একটি NavigationUI ক্লাস অন্তর্ভুক্ত করে। এই ক্লাসে স্ট্যাটিক পদ্ধতি রয়েছে যা উপরের অ্যাপ বার, নেভিগেশন ড্রয়ার এবং নীচের নেভিগেশন দিয়ে নেভিগেশন পরিচালনা করে। যদি আপনার অ্যাপের শীর্ষ-স্তরের গন্তব্যগুলি বৈশিষ্ট্য মডিউল দ্বারা সরবরাহিত UI উপাদানগুলির সমন্বয়ে গঠিত হয়, তবে app মডিউলটি শীর্ষ-স্তরের নেভিগেশন এবং UI উপাদানগুলি রাখার একটি স্বাভাবিক জায়গা। যেহেতু অ্যাপ মডিউলটি সহযোগী বৈশিষ্ট্য মডিউলগুলির উপর নির্ভর করে, তাই তাদের সমস্ত গন্তব্যগুলি আপনার অ্যাপ মডিউলের মধ্যে সংজ্ঞায়িত কোড থেকে অ্যাক্সেসযোগ্য। এর মানে হল যে আইটেমের আইডি যদি গন্তব্যের আইডির সাথে মেলে তাহলে আপনি মেনু আইটেমগুলির সাথে গন্তব্য টাই করতে NavigationUI ব্যবহার করতে পারেন।

চিত্র 2-এ, উদাহরণ app মডিউলটি তার প্রধান কার্যকলাপে একটি BottomNavigationView সংজ্ঞায়িত করে। মেনুতে থাকা মেনু আইটেম আইডিগুলি লাইব্রেরি গ্রাফগুলির নেভিগেশন গ্রাফ আইডিগুলির সাথে মেলে:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@id/home_nav_graph"
        android:icon="@drawable/ic_home"
        android:title="Home"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@id/favorites_nav_graph"
        android:icon="@drawable/ic_favorite"
        android:title="Favorites"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@id/settings_nav_graph"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="ifRoom" />
</menu>

NavigationUI নীচের নেভিগেশন পরিচালনা করতে দিতে, আপনার প্রধান কার্যকলাপ ক্লাসে onCreate() থেকে setupWithNavController() কল করুন, নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController

    findViewById<BottomNavigationView>(R.id.bottom_nav)
            .setupWithNavController(navController)
}

জাভা

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    NavHostFragment navHostFragment =
            (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);

    NavigationUI.setupWithNavController(bottomNav, navController);
}

এই কোডটি জায়গায় রেখে, ব্যবহারকারী যখন নিচের নেভিগেশন আইটেমটিতে ক্লিক করে তখন NavigationUI উপযুক্ত লাইব্রেরি গ্রাফে নেভিগেট করে।

মনে রাখবেন যে আপনার বৈশিষ্ট্য মডিউলগুলির নেভিগেশন গ্রাফের মধ্যে গভীরভাবে এমবেড করা একটি নির্দিষ্ট গন্তব্যের উপর কঠোর নির্ভরতা থাকা আপনার অ্যাপ মডিউলের জন্য সাধারণত খারাপ অনুশীলন। বেশিরভাগ ক্ষেত্রে, আপনি চান যে আপনার অ্যাপ মডিউলটি যেকোন এমবেডেড বা অন্তর্ভুক্ত নেভিগেশন গ্রাফের প্রবেশ বিন্দু সম্পর্কে জানতে চাই (এটি বৈশিষ্ট্য মডিউলের বাইরেও প্রযোজ্য)। আপনি যদি আপনার লাইব্রেরির নেভিগেশন গ্রাফের গভীরে একটি গন্তব্যের সাথে লিঙ্ক করতে চান, তবে এটি করার পছন্দের উপায় হল একটি গভীর লিঙ্ক ব্যবহার করা। অন্য লাইব্রেরির নেভিগেশন গ্রাফে একটি গন্তব্যে নেভিগেট করার জন্য একটি লাইব্রেরির জন্য ডিপ লিঙ্কিংও একমাত্র উপায়।

বৈশিষ্ট্য মডিউল জুড়ে নেভিগেটিং

কম্পাইলের সময়, স্বাধীন বৈশিষ্ট্য মডিউল একে অপরকে দেখতে পারে না, তাই আপনি অন্যান্য মডিউলগুলিতে গন্তব্যে নেভিগেট করতে আইডি ব্যবহার করতে পারবেন না। পরিবর্তে, একটি অন্তর্নিহিত গভীর লিঙ্কের সাথে যুক্ত একটি গন্তব্যে সরাসরি নেভিগেট করতে একটি গভীর লিঙ্ক ব্যবহার করুন

পূর্ববর্তী উদাহরণটি চালিয়ে, কল্পনা করুন যে আপনাকে :feature:home মডিউলের একটি বোতাম থেকে : :feature:settings মডিউলে থাকা একটি গন্তব্যে নেভিগেট করতে হবে। আপনি সেটিংস নেভিগেশন গ্রাফে গন্তব্যের একটি গভীর লিঙ্ক যোগ করে এটি করতে পারেন, যেমন দেখানো হয়েছে:

<?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/settings_nav_graph"
    app:startDestination="@id/settings_fragment_one">

    ...

    <fragment
        android:id="@+id/settings_fragment_two"
        android:name="com.example.google.login.SettingsFragmentTwo"
        android:label="@string/settings_fragment_two" >

        <deepLink
            app:uri="android-app://example.google.app/settings_fragment_two" />
    </fragment>
</navigation>

তারপর হোম ফ্র্যাগমেন্টে বোতামের onClickListener এ নিম্নলিখিত কোড যোগ করুন:

কোটলিন

button.setOnClickListener {
    val request = NavDeepLinkRequest.Builder
        .fromUri("android-app://example.google.app/settings_fragment_two".toUri())
        .build()
    findNavController().navigate(request)
}

জাভা

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        NavDeepLinkRequest request = NavDeepLinkRequest.Builder
            .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two"))
            .build();
        NavHostFragment.findNavController(this).navigate(request);
    }
});

অ্যাকশন বা গন্তব্য আইডি ব্যবহার করে নেভিগেট করার বিপরীতে, আপনি যেকোনো গ্রাফে এমনকি মডিউল জুড়ে যেকোনো URI-তে নেভিগেট করতে পারেন।

URI ব্যবহার করে নেভিগেট করার সময়, ব্যাক স্ট্যাক রিসেট করা হয় না । এই আচরণটি স্পষ্ট গভীর লিঙ্ক নেভিগেশন থেকে ভিন্ন, যেখানে নেভিগেট করার সময় ব্যাক স্ট্যাক প্রতিস্থাপিত হয়।