ডায়নামিক ন্যাভিগেটর লাইব্রেরি জেটপ্যাক নেভিগেশন উপাদানটির কার্যকারিতা প্রসারিত করে যাতে ফিচার মডিউলে সংজ্ঞায়িত গন্তব্যগুলির সাথে কাজ করা যায়। এই গন্তব্যগুলিতে নেভিগেট করার সময় এই লাইব্রেরিটি অন-ডিমান্ড বৈশিষ্ট্য মডিউলগুলির বিরামহীন ইনস্টলেশন সরবরাহ করে।
সেটআপ
বৈশিষ্ট্য মডিউল সমর্থন করতে, আপনার অ্যাপ মডিউলের build.gradle
ফাইলে নিম্নলিখিত নির্ভরতা ব্যবহার করুন:
গ্রোভি
dependencies { def nav_version = "2.8.4" api "androidx.navigation:navigation-fragment-ktx:$nav_version" api "androidx.navigation:navigation-ui-ktx:$nav_version" api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version" }
কোটলিন
dependencies { val nav_version = "2.8.4" api("androidx.navigation:navigation-fragment-ktx:$nav_version") api("androidx.navigation:navigation-ui-ktx:$nav_version") api("androidx.navigation:navigation-dynamic-features-fragment:$nav_version") }
নোট করুন যে অন্যান্য নেভিগেশন নির্ভরতাগুলি এপিআই কনফিগারেশন ব্যবহার করা উচিত যাতে সেগুলি আপনার বৈশিষ্ট্য মডিউলগুলিতে উপলব্ধ থাকে।
মৌলিক ব্যবহার
বৈশিষ্ট্য মডিউল সমর্থন করতে, প্রথমে আপনার অ্যাপে NavHostFragment
এর সমস্ত উদাহরণ androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
এ পরিবর্তন করুন:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:navGraph="@navigation/nav_graph"
... />
এরপরে, একটি DynamicNavHostFragment
এর সাথে যুক্ত আপনার com.android.dynamic-feature
মডিউলের নেভিগেশন গ্রাফে যেকোনো <activity>
, <fragment>
, অথবা <navigation>
গন্তব্যে একটি app:moduleName
অ্যাট্রিবিউট যোগ করুন। এই বৈশিষ্ট্যটি ডায়নামিক নেভিগেটর লাইব্রেরীকে বলে যে গন্তব্যটি আপনার নির্দিষ্ট করা নামের একটি বৈশিষ্ট্য মডিউলের অন্তর্গত।
<fragment
app:moduleName="myDynamicFeature"
android:id="@+id/featureFragment"
android:name="com.google.android.samples.feature.FeatureFragment"
... />
আপনি যখন এই গন্তব্যগুলির মধ্যে একটিতে নেভিগেট করেন, তখন ডায়নামিক নেভিগেটর লাইব্রেরি প্রথমে পরীক্ষা করে যে বৈশিষ্ট্য মডিউলটি ইনস্টল করা আছে কিনা। যদি বৈশিষ্ট্য মডিউলটি ইতিমধ্যেই উপস্থিত থাকে তবে আপনার অ্যাপটি প্রত্যাশা অনুযায়ী গন্তব্যে নেভিগেট করে। মডিউলটি উপস্থিত না থাকলে, আপনার অ্যাপটি একটি মধ্যবর্তী অগ্রগতি খণ্ড গন্তব্য দেখায় কারণ এটি মডিউলটি ইনস্টল করে। অগ্রগতি খণ্ডের ডিফল্ট বাস্তবায়ন একটি অগ্রগতি দণ্ড সহ একটি মৌলিক UI দেখায় এবং যেকোনো ইনস্টলেশন ত্রুটি পরিচালনা করে।
এই UI কাস্টমাইজ করতে, অথবা আপনার নিজের অ্যাপ স্ক্রীন থেকে ইনস্টলেশনের অগ্রগতি ম্যানুয়ালি পরিচালনা করতে, অগ্রগতি খণ্ডটি কাস্টমাইজ করুন এবং এই বিষয়ে অনুরোধের অবস্থার বিভাগগুলি পর্যবেক্ষণ করুন ।
যে গন্তব্যগুলি app:moduleName
নির্দিষ্ট করে না সেগুলি পরিবর্তন ছাড়াই কাজ করতে থাকে এবং এমন আচরণ করে যেন আপনার অ্যাপ একটি নিয়মিত NavHostFragment
ব্যবহার করে৷
অগ্রগতি খণ্ডটি কাস্টমাইজ করুন
আপনি ইনস্টলেশনের অগ্রগতি পরিচালনার জন্য যে গন্তব্যের আইডি ব্যবহার করতে চান সেটিতে app:progressDestination
অ্যাট্রিবিউট সেট করে প্রতিটি নেভিগেশন গ্রাফের জন্য অগ্রগতি খণ্ড বাস্তবায়ন ওভাররাইড করতে পারেন। আপনার কাস্টম অগ্রগতি গন্তব্য হওয়া উচিত একটি Fragment
যা AbstractProgressFragment
থেকে এসেছে। ইনস্টলেশনের অগ্রগতি, ত্রুটি এবং অন্যান্য ইভেন্ট সম্পর্কে বিজ্ঞপ্তিগুলির জন্য আপনাকে অবশ্যই বিমূর্ত পদ্ধতিগুলিকে ওভাররাইড করতে হবে। তারপরে আপনি আপনার পছন্দের একটি UI এ ইনস্টলেশনের অগ্রগতি দেখাতে পারেন।
ডিফল্ট বাস্তবায়নের DefaultProgressFragment
ক্লাস ইনস্টলেশনের অগ্রগতি দেখানোর জন্য এই API ব্যবহার করে।
অনুরোধ রাষ্ট্র নিরীক্ষণ
ডাইনামিক নেভিগেটর লাইব্রেরি আপনাকে অন-ডিমান্ড ডেলিভারির জন্য UX সর্বোত্তম অনুশীলনের অনুরূপ একটি UX ফ্লো বাস্তবায়ন করতে সক্ষম করে, যেখানে একজন ব্যবহারকারী ইনস্টলেশন শেষ হওয়ার জন্য অপেক্ষা করার সময় পূর্ববর্তী স্ক্রিনের প্রসঙ্গে থাকে। এর মানে হল যে আপনাকে কোনও মধ্যবর্তী UI বা অগ্রগতি খণ্ড দেখাতে হবে না।
এই পরিস্থিতিতে, আপনি সমস্ত ইনস্টলেশন অবস্থা, অগ্রগতি পরিবর্তন, ত্রুটি, ইত্যাদি পর্যবেক্ষণ এবং পরিচালনার জন্য দায়ী।
এই নন-ব্লকিং নেভিগেশন ফ্লো শুরু করতে, একটি DynamicExtras
অবজেক্ট পাস করুন যাতে একটি DynamicInstallMonitor
আছে NavController.navigate()
এ, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) )
জাভা
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); )
navigate()
কল করার সাথে সাথেই, আপনাকে installMonitor.isInstallRequired
এর মান পরীক্ষা করে দেখতে হবে যে নেভিগেশনের প্রচেষ্টার ফলে একটি বৈশিষ্ট্য মডিউল ইনস্টলেশন হয়েছে কিনা।
- মানটি
false
হলে, আপনি একটি স্বাভাবিক গন্তব্যে নেভিগেট করছেন এবং অন্য কিছু করার দরকার নেই৷ মানটি
true
হলে, আপনারLiveData
অবজেক্টটি পর্যবেক্ষণ করা শুরু করা উচিত যা এখনinstallMonitor.status
এ রয়েছে। এইLiveData
অবজেক্ট প্লে কোর লাইব্রেরি থেকেSplitInstallSessionState
আপডেট নির্গত করে। এই আপডেটগুলিতে ইনস্টলেশনের অগ্রগতি ইভেন্ট রয়েছে যা আপনি UI আপডেট করতে ব্যবহার করতে পারেন। প্রয়োজনে ব্যবহারকারীর নিশ্চিতকরণের জন্য জিজ্ঞাসা সহ প্লে কোর গাইডে বর্ণিত সমস্ত প্রাসঙ্গিক স্থিতিগুলি পরিচালনা করতে মনে রাখবেন।কোটলিন
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) ) if (installMonitor.isInstallRequired) { installMonitor.status.observe(this, object : Observer<SplitInstallSessionState> { override fun onChanged(sessionState: SplitInstallSessionState) { when (sessionState.status()) { SplitInstallSessionStatus.INSTALLED -> { // Call navigate again here or after user taps again in the UI: // navController.navigate(destinationId, destinationArgs, null, null) } SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> { SplitInstallManager.startConfirmationDialogForResult(...) } // Handle all remaining states: SplitInstallSessionStatus.FAILED -> {} SplitInstallSessionStatus.CANCELED -> {} } if (sessionState.hasTerminalStatus()) { installMonitor.status.removeObserver(this); } } }); }
জাভা
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); ) if (installMonitor.isInstallRequired()) { installMonitor.getStatus().observe(this, new Observer<SplitInstallSessionState>() { @Override public void onChanged(SplitInstallSessionState sessionState) { switch (sessionState.status()) { case SplitInstallSessionStatus.INSTALLED: // Call navigate again here or after user taps again in the UI: // navController.navigate(mDestinationId, mDestinationArgs, null, null); break; case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION: SplitInstallManager.startConfirmationDialogForResult(...) break; // Handle all remaining states: case SplitInstallSessionStatus.FAILED: break; case SplitInstallSessionStatus.CANCELED: break; } if (sessionState.hasTerminalStatus()) { installMonitor.getStatus().removeObserver(this); } } }); }
ইনস্টলেশন শেষ হলে, LiveData
অবজেক্ট একটি SplitInstallSessionStatus.INSTALLED
অবস্থা নির্গত করে। তারপরে আপনাকে আবার NavController.navigate()
কল করতে হবে। যেহেতু মডিউলটি এখন ইনস্টল করা হয়েছে, কলটি এখন সফল হয়েছে, এবং অ্যাপটি প্রত্যাশা অনুযায়ী গন্তব্যে নেভিগেট করে।
একটি টার্মিনাল অবস্থায় পৌঁছানোর পরে, যেমন ইনস্টলেশন সম্পূর্ণ হলে বা ইনস্টলেশন ব্যর্থ হলে, মেমরি লিক এড়াতে আপনার LiveData
পর্যবেক্ষককে সরিয়ে দেওয়া উচিত। আপনি SplitInstallSessionStatus.hasTerminalStatus()
ব্যবহার করে স্ট্যাটাসটি একটি টার্মিনাল অবস্থার প্রতিনিধিত্ব করে কিনা তা পরীক্ষা করতে পারেন।
এই পর্যবেক্ষকের একটি উদাহরণ বাস্তবায়নের জন্য AbstractProgressFragment
দেখুন।
গ্রাফ অন্তর্ভুক্ত
ডায়নামিক নেভিগেটর লাইব্রেরি ফিচার মডিউলে সংজ্ঞায়িত গ্রাফ সহ সমর্থন করে। একটি বৈশিষ্ট্য মডিউলে সংজ্ঞায়িত একটি গ্রাফ অন্তর্ভুক্ত করতে, নিম্নলিখিতগুলি করুন:
<include
<include/>
এর পরিবর্তে<include-dynamic/>
ব্যবহার করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:<include-dynamic android:id="@+id/includedGraph" app:moduleName="includedgraphfeature" app:graphResName="included_feature_nav" app:graphPackage="com.google.android.samples.dynamic_navigator.included_graph_feature" />
<include-dynamic ... />
এর ভিতরে, আপনাকে অবশ্যই নিম্নলিখিত বৈশিষ্ট্যগুলি নির্দিষ্ট করতে হবে:-
app:graphResName
: নেভিগেশন গ্রাফ রিসোর্স ফাইলের নাম। নামটি গ্রাফের ফাইলের নাম থেকে নেওয়া হয়েছে। উদাহরণস্বরূপ, যদি গ্রাফটিres/navigation/nav_graph.xml
এ থাকে, তাহলে রিসোর্সের নাম হলnav_graph
। -
android:id
- গ্রাফ গন্তব্য আইডি। ডায়নামিক নেভিগেটর লাইব্রেরি অন্তর্ভুক্ত গ্রাফের মূল উপাদানে পাওয়া যেকোনandroid:id
মানকে উপেক্ষা করে। -
app:moduleName
: মডিউলটির প্যাকেজ নাম।
-
সঠিক গ্রাফপ্যাকেজ ব্যবহার করুন
app:graphPackage
সঠিক কারণ ন্যাভিগেশন উপাদানটি বৈশিষ্ট্য মডিউল থেকে নির্দিষ্ট navGraph
অন্তর্ভুক্ত করতে সক্ষম হবে না, অন্যথায়।
একটি ডাইনামিক ফিচার মডিউলের প্যাকেজ নামটি বেস অ্যাপ মডিউলের applicationId
মডিউলের নাম যুক্ত করে তৈরি করা হয়। তাই যদি বেস অ্যাপ মডিউলে com.example.dynamicfeatureapp
এর একটি applicationId
থাকে এবং ডায়নামিক ফিচার মডিউলটির নাম হয় DynamicFeatureModule
, তাহলে ডায়নামিক মডিউলটির প্যাকেজের নাম হবে com.example.dynamicfeatureapp.DynamicFeatureModule
। এই প্যাকেজের নাম কেস-সংবেদনশীল।
আপনার যদি কোনো সন্দেহ থাকে, তাহলে আপনি জেনারেট করা AndroidManifest.xml
চেক করে ফিচার মডিউলের প্যাকেজের নাম নিশ্চিত করতে পারেন। প্রকল্পটি তৈরি করার পরে <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml
এ যান, যা দেখতে এইরকম কিছু হওয়া উচিত:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" featureSplit="DynamicFeatureModule" package="com.example.dynamicfeatureapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <dist:module dist:instant="false" dist:title="@string/title_dynamicfeaturemodule" > <dist:delivery> <dist:install-time /> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module> <application /> </manifest>
featureSplit
মানটি ডায়নামিক ফিচার মডিউলের নামের সাথে মেলে এবং প্যাকেজটি বেস অ্যাপ মডিউলের applicationId
সাথে মিলবে। app:graphPackage
হল এইগুলির সংমিশ্রণ: com.example.dynamicfeatureapp.DynamicFeatureModule
।
একটি অন্তর্ভুক্ত-গতিশীল নেভিগেশন গ্রাফে নেভিগেট করা
একটি include-dynamic
নেভিগেশন গ্রাফের startDestination
নেভিগেট করা শুধুমাত্র সম্ভব। ডায়নামিক মডিউলটি তার নিজস্ব নেভিগেশন গ্রাফের জন্য দায়ী এবং বেস অ্যাপের সে সম্পর্কে কোন জ্ঞান নেই।
অন্তর্ভুক্ত-ডাইনামিক মেকানিজম বেস অ্যাপ মডিউলকে একটি নেস্টেড নেভিগেশন গ্রাফ অন্তর্ভুক্ত করতে সক্ষম করে যা ডাইনামিক মডিউলের মধ্যে সংজ্ঞায়িত করা হয়। এই নেস্টেড নেভিগেশন গ্রাফ যেকোনো নেস্টেড নেভিগেশন গ্রাফের মতো আচরণ করে। রুট নেভিগেশন গ্রাফ (অর্থাৎ, নেস্টেড গ্রাফের অভিভাবক) শুধুমাত্র নেস্টেড নেভিগেশন গ্রাফটিকেই একটি গন্তব্য হিসেবে সংজ্ঞায়িত করতে পারে এবং এর সন্তানদের নয়। সুতরাং, যখন অন্তর্ভুক্ত-গতিশীল নেভিগেশন গ্রাফ গন্তব্য হয় তখন startDestination
ব্যবহার করা হয়।
সীমাবদ্ধতা
- গতিশীল-অন্তর্ভুক্ত গ্রাফ বর্তমানে গভীর লিঙ্ক সমর্থন করে না।
- গতিশীলভাবে লোড করা নেস্টেড গ্রাফ (অর্থাৎ, একটি
app:moduleName
সহ একটি<navigation>
উপাদান) বর্তমানে গভীর লিঙ্কগুলিকে সমর্থন করে না।