ডেস্টিনেশনে লজিক বা র‍্যাপার প্রয়োগ করা

আপনি অতিরিক্ত তথ্য প্রদান করতে পারেন অথবা NavEntryDecorator ক্লাস ব্যবহার করে ডেস্টিনেশনে একই যুক্তি প্রয়োগ করতে পারেন। এই ক্লাসটি প্রতিটি NavEntry-কে কম্পোজ করা যায় এমন ফাংশন সহ ব্যাক স্ট্যাকে র‍্যাপ করে। অন্যভাবে বলতে গেলে, এটি এন্ট্রির কন্টেন্টকে সাজিয়ে তোলে।

কাস্টম ডেকোরেটর তৈরি করা

ডেকোরেটর তৈরি করতে, NavEntryDecorator ক্লাস এক্সটেন্ড করুন এবং নিম্নলিখিত পদ্ধতি ওভাররাইড করুন:

  • decorate - আপনার ব্যাক স্ট্যাকের প্রতিটি NavEntry-এর জন্য কল করা যায় এমন কম্পোজ করা যায় এমন ল্যাম্বডা। এটি NavEntry-কে প্যারামিটার হিসেবে গ্রহণ করে। এটি আপনাকে এন্ট্রি contentKey-এর সাথে কী করা স্টেট অবজেক্ট তৈরি করতে দেয়। আপনি এন্ট্রি কন্টেন্টের জন্য ডিপেন্ডেন্সি প্রদান করতে CompositionLocalProvider ব্যবহার করতে পারবেন। এছাড়াও, আপনি কন্টেন্টকে কম্পোজ করা যায় এমন ফাংশন দিয়ে ঘিরে রাখতে পারেন অথবা সাইড-ইফেক্ট ট্রিগার করতে পারেন। এই পদ্ধতির মধ্যে আপনাকে সবসময় entry.Content() কল করতে হবে।
  • onPop - A callback that is invoked when a NavEntry has been removed from the back stack and has left the composition. এটি সরিয়ে দেওয়া এন্ট্রির contentKey পায়। সেই এন্ট্রির সাথে যুক্ত যেকোনও স্টেট শনাক্ত ও ক্লিন-আপ করতে contentKey ব্যবহার করুন।

নিচের উদাহরণটি NavEntryDecorator ক্লাসকে এক্সটেন্ড করে কাস্টম ডেকরেটর তৈরি করে।

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

আপনার ডেকরেটরের যদি স্টেটের অ্যাক্সেস প্রয়োজন হয়, তাহলে এমন একটি কম্পোজ করার উপযুক্ত ফাংশন তৈরি করুন যা সেই স্টেট তৈরি করে এবং তারপরে ডেকরেটর তৈরি করতে এটি ব্যবহার করে। ইমপ্লিমেন্টেশনের উদাহরণ দেখতে, rememberSaveableStateHolderNavEntryDecorator-এর সোর্স কোড দেখুন। এটি স্টেট - একটি SaveableStateHolder - তৈরি করে এবং ডেকোরেটর কনস্ট্রাক্ট করতে এটি ব্যবহার করে।

ব্যাক স্ট্যাক সাজানো

আপনার NavEntryDecorator তৈরি করা হয়ে গেলে, দুটি উপায়ের মধ্যে যেকোনও একটিতে আপনার ব্যাক স্ট্যাকের এন্ট্রি সাজান:

  • rememberDecoratedNavEntries ব্যবহার করুন। আপনার একাধিক ব্যাক স্ট্যাক থাকলে, এই ফাংশনটি কাজে লাগে, প্রতিটি ব্যাক স্ট্যাকের নিজস্ব ডেকোরেটর সেট থাকে (আরও বিবরণের জন্য এই কোড রেসিপি দেখুন)। এই ফাংশনটি NavDisplay-এর সাথে ব্যবহার করা যায় এমন NavEntry-এর একটি সাজানো তালিকা রিটার্ন করে।
  • entryDecorators প্যারামিটার ব্যবহার করে আপনার ডেকোরেটরকে সরাসরি NavDisplay-এ সাপ্লাই করুন। NavDisplay কল rememberDecoratedNavEntries করে এবং সাজানো এন্ট্রি দেখায়।

ডিফল্ট ডেকরেটর যোগ করুন

Navigation 3-এ SaveableStateHolderNavEntryDecorator নামের একটি ডিফল্ট ডেকোরেটর থাকে যা কনফিগারেশন পরিবর্তন ও প্রসেস ডেথের মাধ্যমে NavEntry-এর স্টেটকে রিটেন করে। এটি SaveableStateProvider-এর মাধ্যমে NavEntry কন্টেন্টকে র‍্যাপ করে, যা NavEntry কন্টেন্টের মধ্যে rememberSaveable কলকে সঠিকভাবে কাজ করতে দেয়।

আপনার ডেকোরেটর SaveableStateProvider না দিলে, আপনাকে সাপ্লাই করা ডেকোরেটরের তালিকায় প্রথম ডেকোরেটর হিসেবে SaveableStateHolderNavEntryDecorator যোগ করতে হবে। এটি rememberSaveableStateHolderNavEntryDecorator ব্যবহার করে তৈরি করা হয়েছে।

যেমন:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

ResultEventBusNavEntryDecorator ব্যবহার করে ফলাফল পাস করা

Navigation 3 1.2.0 থেকে শুরু করে, আপনি ResultEventBusNavEntryDecorator ব্যবহার করে প্রতিটি NavEntry-এ ResultEventBus দিতে পারবেন, এর জন্য LocalResultEventBus কম্পোজিশন লোকাল ব্যবহার করতে হবে।

ডিফল্ট হিসেবে, rememberResultEventBusNavEntryDecorator ইন্টার্নালি নিজের ResultEventBus ইনস্ট্যান্স তৈরি করে ও মনে রাখে rememberResultEventBus ব্যবহার করে। আপনি যদি ডেকোরেটর হায়ারার্কির বাইরে ইভেন্ট বাস অ্যাক্সেস করতে চান (যেমন, টপ-লেভেল অ্যাপ স্ক্যাফোল্ডিং), তাহলে আপনি rememberResultEventBus কল করে এবং এটিকে rememberResultEventBusNavEntryDecorator(resultEventBus)-এ পাস করে ResultEventBus হোয়েস্ট করতে পারেন:

val resultEventBus = rememberResultEventBus()

NavDisplay(
    /* ... */
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus)
    )
)

ফলাফল পাঠানো ও পর্যবেক্ষণ করা সম্পর্কে আরও বিবরণের জন্য, ফলাফল ফেরত দেওয়া দেখুন।

কখন ডেকোরেটর ব্যবহার করতে হয়

এগুলি করতে ডেকোরেটর ব্যবহার করুন:

  • ব্যাক স্ট্যাকে থাকা প্রতিটি NavEntry-এর জন্য একটি করে ডিপেন্ডেন্সি তৈরি করুন। যেমন, ViewModelStoreNavEntryDecorator প্রতিটি NavEntry-এর জন্য একটি ViewModelStore তৈরি করে।
  • ফলাফল পাস করা এবং গন্তব্যগুলির মধ্যে যোগাযোগ করা। যেমন, ResultEventBusNavEntryDecorator ব্যাক স্ট্যাকের গন্তব্যে যাওয়ার জন্য ResultEventBus প্রদান করে।
  • একাধিক NavEntry-এর সাথে কোনও অবজেক্টের স্কোপ। যেমন, একাধিক এন্ট্রির মধ্যে ViewModel শেয়ার করতে।
  • একাধিক NavEntry-এর জন্য একই অ্যাকশন পারফর্ম করুন। যেমন, প্রতিটি এন্ট্রির জন্য লগ করা, ডিবাগ করা বা ট্রেস করা অপারেশন পারফর্ম করতে।
  • একই কম্পোজেবল ফাংশন দিয়ে NavEntrys র‍্যাপ করুন।
  • NavEntry-এর সাথে যুক্ত স্টেট পরিষ্কার করুন। যেমন, ব্যাক স্ট্যাক থেকে কোনও এন্ট্রি সরিয়ে দেওয়া হলে, এর সাথে যুক্ত ViewModelStore ViewModelStoreNavEntryDecorator মুছে যায়।

এইসব ক্ষেত্রে ডেকোরেটর ব্যবহার করবেন না:

  • একটি NavEntry-তে নির্ভরতা পাস করুন।
  • ব্যাক স্ট্যাকের চেয়ে বেশি স্কোপ আছে এমন ডিপেন্ডেন্সি প্রদান করুন।

এইসব ক্ষেত্রে, NavEntry তৈরি করার সময় সরাসরি ডিপেন্ডেন্সি পাস করুন।

কোডের আরও উদাহরণ দেখতে, NavEntryDecorator দেখুন।