মাল্টি-মডিউল প্রোজেক্টের জন্য নেভিগেশন সংক্রান্ত পেশাদার পদ্ধতি

নেভিগেশন গ্রাফে নিম্নলিখিত যেকোনও কম্বিনেশন থাকতে পারে:

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

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

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

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

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

গ্ৰুভি

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

Kotlin

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 ব্যবহার করে মেনু আইটেমের সাথে গন্তব্য লিঙ্ক করতে পারবেন।

ছবি ২-এ, উদাহরণ হিসেবে দেখানো 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() কল করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Kotlin

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-এ নিম্নলিখিত কোড যোগ করুন:

Kotlin

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 ব্যবহার করে নেভিগেট করার সময়, ব্যাক স্ট্যাক রিসেট করা হয় না। এই আচরণটি এক্সপ্লিসিট ডিপ লিংক নেভিগেশন-এর মতো নয়, যেখানে নেভিগেট করার সময় ব্যাক স্ট্যাক পরিবর্তন করা হয়।