Navigation 3 1.2.0 থেকে শুরু করে, আপনি ResultEventBus
API ব্যবহার করে
ডেস্টিনেশন থেকে ফলাফল পেতে পারবেন।
ResultEventBus দুটি কমিউনিকেশন মডেল প্রদান করে:
- ইভেন্ট-ভিত্তিক ফলাফল: ক্ষণস্থায়ী, এককালীন ইভেন্টের (যেমন, কনফার্মেশন স্নাকবার দেখানো বা কোনও সাইড এফেক্ট ট্রিগার করা) জন্য
ResultEffectব্যবহার করুন। - রাজ্য-ভিত্তিক ফলাফল: কম্পোজ
Stateব্যবহার করেconflateAsStateহিসেবে লেটেস্ট ফলাফল দেখার জন্য।
ফলাফল ইভেন্ট বাস সেট-আপ করা
আপনার কম্পোজ করা যায় এমন গন্তব্যের জন্য ResultEventBus উপলভ্য করতে, আপনার NavDisplay-এ পাস করা
ডেকরেশনের তালিকায়
rememberResultEventBusNavEntryDecorator যোগ করুন। এটি প্রতিটি
ডেস্টিনেশনের কন্টেন্টকে LocalResultEventBus
লোকাল কম্পোজিশন প্রদান করে।
NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator() ) )
ফলাফলের কী
ResultEventBus একটি কী ব্যবহার করে প্রতিটি ফলাফল শনাক্ত করে এবং রাউট করে। প্রেরক ও
প্রাপক একই কী ব্যবহার করে ফলাফল ম্যাচ করে।
আপনি দু'ভাবে ফলাফল কী নির্দিষ্ট করতে পারবেন:
- স্পষ্ট কী: আপনি একটি স্পষ্ট কী নির্দিষ্ট করতে পারেন (যেমন
resultKey = "pickup_address")। সাধারণ ধরনের (যেমনString,Booleanবা আদিম) রিটার্ন করার সময় অথবা একাধিক ডেস্টিনেশন একই ডেটা টাইপের আলাদা আলাদা ইনস্ট্যান্স রিটার্ন করলে স্পষ্ট কী ব্যবহার করুন। - টাইপ-ডেরাইভড কী: আপনি কোনও স্পষ্ট কী নির্দিষ্ট না করলে,
ResultEventBusঅটোমেটিকtoStringফলাফলের ধরনের উপস্থাপনাKClassব্যবহার করে একটি কী জেনারেট করে (যেমনContact::class.toString())। আলাদা, ডোমেন-নির্দিষ্ট ডেটা ধরনের জন্য টাইপ-ডেরাইভড কী ব্যবহার করুন।
কোনও গন্তব্য থেকে ফলাফল দেখানো
স্ক্রিন কম্পোজ করার উপযুক্ত আইটেম যাতে আবার ব্যবহার করা যায় এবং পরীক্ষা করা যায়, সেই জন্য আপনার স্ক্রিন UI-এর মধ্যে
LocalResultEventBus সরাসরি অ্যাক্সেস করবেন না। পরিবর্তে, আপনার স্ক্রিন থেকে কলব্যাক
ল্যাম্বডা এক্সপোজ করুন। আপনার entryProvider-এ, LocalResultEventBus.current ব্যবহার করে ফলাফল পাঠিয়ে
এবং ফিরে গিয়ে কলব্যাক হ্যান্ডেল করুন।
আপনি একটি স্পষ্ট ফলাফল কী ব্যবহার করে ফলাফল পাঠাতে পারেন:
import androidx.compose.runtime.Composable import androidx.navigation3.runtime.result.LocalResultEventBus entry<AddressPickerRoute> { val resultBus = LocalResultEventBus.current AddressPickerScreen( onAddressSelected = { selectedAddress: Address -> resultBus.sendResult( resultKey = "pickup_address", result = selectedAddress ) navigator.goBack() } ) }
এছাড়াও, আপনি টাইপ-ডেরাইভড কী ব্যবহার করে ফলাফল পাঠাতে পারবেন:
import androidx.compose.runtime.Composable import androidx.navigation3.runtime.result.LocalResultEventBus entry<ContactPickerRoute> { val resultBus = LocalResultEventBus.current ContactPickerScreen( onContactSelected = { selectedContact: Contact -> resultBus.sendResult(result = selectedContact) navigator.goBack() } ) }
ফলাফল পাওয়া
ডেস্টিনেশন, ইভেন্ট-ভিত্তিক প্রভাব বা স্টেট-ভিত্তিক অবজার্ভেবল ব্যবহার করে ফলাফল কনজিউম করতে পারে।
| API | আচরণ | সাজেস্ট করা ব্যবহারের ক্ষেত্র |
|---|---|---|
ResultEffect |
সারিভুক্ত করা হয়েছে: কী-এর জন্য নির্গত সমস্ত ফলাফলকে ক্রম অনুযায়ী প্রসেস করে। | এককালীন ইভেন্ট ও পার্শ্ব প্রতিক্রিয়া (যেমন, স্নাকবার দেখানো বা ViewModel-এ ফরওয়ার্ড করা)। |
conflateAsState |
একত্রিত করা: মধ্যবর্তী ফলাফল বাদ দেয় এবং Compose State হিসেবে শুধুমাত্র লেটেস্ট ফলাফল রেখে দেয়। |
লাইটওয়েট UI স্টেট মডিফায়ার (যেমন, অ্যাক্টিভ ফিল্টার ট্যাগ বা বেছে নেওয়ার ওভাররাইড)। |
ResultEffect-এর মাধ্যমে এককালীন ইভেন্ট ম্যানেজ করা
এককালীন ইভেন্ট ম্যানেজ করার সময় ResultEffect ব্যবহার করুন, যেমন
অ্যানালিটিক্স ট্রিগার করা, স্নাকবার দেখানো বা কোনও ফলাফল
ViewModel-এ ফরোয়ার্ড করা।
ResultEffect ইনকামিং ফলাফলের জন্য একটি সারি বজায় রাখে। কোনও নির্দিষ্ট কী-এর জন্য একাধিক ফলাফল
পাঠানো হলে, ResultEffect প্রতিটি ফলাফলকে সেই ক্রমে প্রসেস করে যে ক্রমে সেটি
পাঠানো হয়েছে। এছাড়াও, ResultEffect একটি কোরাউটিন স্কোপে রান করে, যা আপনাকে
প্রভাবের বডির মধ্যে সরাসরি সাসপেন্ড করা ফাংশন কল করতে দেয়।
আপনি অনুপযুক্ত ফলাফল কী সম্পর্কিত ফলাফল শুনতে পারেন:
import androidx.compose.runtime.Composable import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation3.runtime.result.ResultEffect @Composable fun RideSummaryScreen( onOpenAddressPicker: (key: String) -> Unit, viewModel: RideSummaryViewModel = viewModel() ) { ResultEffect<Address>(resultKey = "pickup_address") { address -> viewModel.onPickupAddressSelected(address) } ResultEffect<Address>(resultKey = "destination_address") { address -> viewModel.onDestinationAddressSelected(address) } RideSummaryContent( pickupAddress = viewModel.pickupAddress, destinationAddress = viewModel.destinationAddress, onPickPickup = { onOpenAddressPicker("pickup_address") }, onPickDestination = { onOpenAddressPicker("destination_address") } ) }
এছাড়াও, আপনি টাইপ-ডেরাইভড কী ব্যবহার করে ফলাফল শুনতে পারেন:
import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation3.runtime.result.ResultEffect @Composable fun ComposeMessageScreen( onPickContact: () -> Unit, snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }, viewModel: ComposeMessageViewModel = viewModel() ) { ResultEffect<Contact> { contact -> // Suspending calls are supported directly in the effect body snackbarHostState.showSnackbar("Selected ${contact.name}") viewModel.onRecipientSelected(contact) } ComposeMessageContent( recipient = viewModel.recipient, onPickContact = onPickContact ) }
দুটি গন্তব্যের মধ্যে নেভিগেট করার সময়, ResultEffect নিম্নলিখিত লাইফসাইকেল সিকোয়েন্সের
মাধ্যমে এক্সিকিউট করে:
- প্রেরক এমিট করে: প্রেরকের গন্তব্য
resultBus.sendResult(resultKey = "pickup_address", address)ব্যবহার করে ফলাফল পাঠায় এবং ব্যাক স্ট্যাক পপ করে। - প্রাপক কম্পোজিশন লেখেন: প্রাপকের গন্তব্য
অ্যাক্টিভ স্ক্রিন হয়ে যায় এবং
ResultEffectফলাফল শোনার জন্য অপেক্ষা করতে থাকে। - প্রাপক ফলাফল প্রসেস করে:
ResultEffectসেই কী-এর জন্য পাঠানো প্রতিটি ফলাফলের জন্য এর ইফেক্ট বডি পায় ও এক্সিকিউট করে, সব নির্গমনকে সেই ক্রমে প্রসেস করে যে ক্রমে সেগুলি পাঠানো হয়েছিল। - প্রাপক কম্পোজিশন ছেড়ে বেরিয়ে যায়: ব্যাক স্ট্যাক থেকে প্রাপকের ডেস্টিনেশন পপ-আপ
হয়ে গেলে,
ResultEffectকম্পোজিশন ছেড়ে বেরিয়ে যায় এবং ফলাফল শোনা বন্ধ করে দেয়।
conflateAsState-এর সাথে রাজ্য হিসেবে লেটেস্ট ফলাফল দেখুন
আপনি যদি সরাসরি লোকাল UI
স্টেট পরিবর্তন বা ফিল্টার করার জন্য শুধুমাত্র লেটেস্ট ফলাফলের ভ্যালু চান এবং ফলাফল আপডেট হলেই Compose অটোমেটিক রিকম্পোজ করতে চান,
তাহলে ResultEventBus-এ conflateAsState কল করুন।
আপনি অনুপযুক্ত ফলাফল কী সম্পর্কিত ফলাফল দেখতে পাবেন:
import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.graphics.Color import androidx.navigation3.runtime.result.LocalResultEventBus @Composable fun ThemePreviewScreen( onOpenColorPicker: (key: String) -> Unit ) { val resultBus = LocalResultEventBus.current val primaryColor by resultBus.conflateAsState<Color>( resultKey = "primary_color", defaultValue = MaterialTheme.colorScheme.primary ) val accentColor by resultBus.conflateAsState<Color>( resultKey = "accent_color", defaultValue = MaterialTheme.colorScheme.tertiary ) ThemePreviewContent( primaryColor = primaryColor, accentColor = accentColor, onPickPrimary = { onOpenColorPicker("primary_color") }, onPickAccent = { onOpenColorPicker("accent_color") } ) }
এছাড়াও, আপনি টাইপ-ডেরাইভড কী ব্যবহার করে ফলাফল দেখতে পারেন:
import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.navigation3.runtime.result.LocalResultEventBus @Composable fun FilterableProductListScreen( initialFilter: ProductFilter = ProductFilter.All, onOpenFilterPicker: () -> Unit ) { val resultBus = LocalResultEventBus.current // Observe latest filter result as Compose State, starting with initialFilter val activeFilter by resultBus.conflateAsState<ProductFilter>( defaultValue = initialFilter ) ProductListContent( activeFilter = activeFilter, onOpenFilterPicker = onOpenFilterPicker ) }
Hoist ResultEventBus
ডিফল্ট হিসেবে, rememberResultEventBusNavEntryDecorator ইন্টার্নালি
rememberResultEventBus ব্যবহার করে
নিজের ResultEventBus তৈরি করে ও মনে রাখে।
আপনার প্রয়োজন হলে, আপনি স্পষ্টভাবে ResultEventBus তৈরি ও হোইস্ট করতে পারবেন:
ResultEventBusইনস্ট্যান্স সরাসরি কম্পোজ করা যায় না এমন কম্পোনেন্ট বা ডিপেন্ডেন্সি ইনজেকশন গ্রাফে পাস করুন।- ডেস্টিনেশন হায়ারার্কির বাইরে টপ-লেভেল অ্যাপ স্ক্যাফোল্ডিং (যেমন, অ্যাপ বার বা নেভিগেশন ড্রয়ার) থেকে ফলাফল পাঠানো বা পর্যবেক্ষণ করা।
ResultEventBus-কে হোয়েস্ট করতে, rememberResultEventBus ব্যবহার করে এটি তৈরি করুন এবং
rememberResultEventBusNavEntryDecorator(resultEventBus)-এ পাস করুন:
import androidx.compose.runtime.Composable import androidx.navigation3.runtime.result.rememberResultEventBus import androidx.navigation3.runtime.result.rememberResultEventBusNavEntryDecorator import androidx.navigation3.ui.NavDisplay // Hoist the ResultEventBus at the top level val resultEventBus = rememberResultEventBus() // Pass the hoisted bus to the decorator val resultEventBusNavEntryDecorator = rememberResultEventBusNavEntryDecorator<NavKey>( resultEventBus = resultEventBus ) NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), resultEventBusNavEntryDecorator ) )
ফলাফল ম্যানেজ ও মুছে দেওয়া
কোনও ডেস্টিনেশন একবারের ফলাফল ব্যবহার করে নিলে, removeResult ব্যবহার করে ইভেন্ট বাস থেকে সেটি সরিয়ে দিন। ডেস্টিনেশন আবার কম্পোজিশনে প্রবেশ করলে, এটি নতুন পর্যবেক্ষকদের কাছে
পুরনো ইভেন্ট আবার ডেলিভার করা থেকে বাসকে বাধা দেয়:
import androidx.compose.runtime.Composable import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation3.runtime.result.LocalResultEventBus import androidx.navigation3.runtime.result.ResultEffect @Composable fun NotificationSettingsScreen( viewModel: NotificationViewModel = viewModel() ) { val resultBus = LocalResultEventBus.current ResultEffect<ConfirmationResult>(resultKey = "confirm_permission") { confirmation -> viewModel.onPermissionConfirmed(confirmation) // Clear the result after consumption to prevent re-delivery resultBus.removeResult(resultKey = "confirm_permission") } }
আপনি নির্দিষ্ট কী (resultBus.removeResult(resultKey)) বা
টাইপ-ডেরাইভড কী (resultBus.removeResult<T>()) ব্যবহার করে ফলাফল মুছে দিতে পারেন। কী
ম্যাচিংয়ের বিবরণ পেতে, ফলাফলের কী দেখুন।
রেসিপি
বিভিন্ন ফলাফল পাস করার কৌশল ডেমোনস্ট্রেট করা সম্পূর্ণ রান করার মতো কোডের উদাহরণের জন্য, নিম্নলিখিত রেসিপি দেখুন:
- ইভেন্ট-ভিত্তিক ফলাফল রেসিপি
- রাজ্য-ভিত্তিক ফলাফল রেসিপি
- সিরিয়ালাইজ করা যায় এমন ফলাফল সংক্রান্ত রেসিপি