नेविगेशन कॉम्पोनेंट प्रोग्राम के हिसाब से, प्रोजेक्ट बनाने और इंटरैक्ट करने के तरीके उपलब्ध कराता है इस्तेमाल किए जा सकते हैं.
NavHostफ़्रैगमेंट बनाएं
Google Analytics 4 पर माइग्रेट करने के लिए,
NavHostFragment.create()
प्रोग्राम बनाकर किसी खास ग्राफ़ रिसॉर्स के साथ NavHostFragment
बनाना हो,
जैसा कि नीचे उदाहरण में दिखाया गया है:
Kotlin
val finalHost = NavHostFragment.create(R.navigation.example_graph) supportFragmentManager.beginTransaction() .replace(R.id.nav_host, finalHost) .setPrimaryNavigationFragment(finalHost) // equivalent to app:defaultNavHost="true" .commit()
Java
NavHostFragment finalHost = NavHostFragment.create(R.navigation.example_graph); getSupportFragmentManager().beginTransaction() .replace(R.id.nav_host, finalHost) .setPrimaryNavigationFragment(finalHost) // equivalent to app:defaultNavHost="true" .commit();
ध्यान दें कि setPrimaryNavigationFragment(finalHost)
आपका NavHost
इंटरसेप्ट सिस्टम के वापस जाने वाले बटन को दबाने पर ऐसा होता है. इस व्यवहार को यहां भी लागू किया जा सकता है:
app:defaultNavHost="true"
जोड़कर, अपना NavHost
एक्सएमएल. अगर आपको
पसंद के मुताबिक 'वापस जाएं' बटन का व्यवहार
और नहीं चाहते कि आपका NavHost
वापस जाएं बटन दबाए, तो आप
setPrimaryNavigationFragment()
के लिए null
.
NavBackStackEntry का इस्तेमाल करके किसी डेस्टिनेशन का रेफ़रंस दें
नेविगेशन 2.2.0 से शुरू करके, आप
NavBackStackEntry
नेविगेशन स्टैक पर किसी भी डेस्टिनेशन के लिए कॉल करें
NavController.getBackStackEntry()
,
उसे एक डेस्टिनेशन आईडी भेजना. अगर पिछली गतिविधियों में एक से ज़्यादा इंस्टेंस हैं
दिए गए डेस्टिनेशन में से, getBackStackEntry()
सबसे ऊपर वाला इंस्टेंस लौटाता है
से हटा दिया जाएगा.
वापस लौटाए गए NavBackStackEntry
से
Lifecycle
,
ViewModelStore
और
SavedStateRegistry
डेस्टिनेशन के लेवल पर. ये ऑब्जेक्ट, पिछली गतिविधियों पर डेस्टिनेशन के लाइफ़टाइम के लिए मान्य हैं. जब संबंधित गंतव्य पॉप-अप होता है
पिछली गतिविधियों में शामिल हो जाते हैं, Lifecycle
को नष्ट कर दिया जाता है, और स्टेटस अब सेव नहीं किया जाता है. साथ ही, ViewModel
ऑब्जेक्ट को हटा दिया जाता है.
ये प्रॉपर्टी आपको ViewModel
ऑब्जेक्ट के लिए Lifecycle
और स्टोर देती हैं और
इन क्लास के साथ काम करती हैं
सेव की गई स्थिति, कोई भी
आप किस तरह के गंतव्य का उपयोग करते हैं. यह खास तौर पर तब मददगार होता है, जब
ऐसे डेस्टिनेशन टाइप जिनमें अपने-आप जुड़ा हुआ Lifecycle
नहीं होता,
जैसे कि कस्टम डेस्टिनेशन.
उदाहरण के लिए, NavBackStackEntry
के Lifecycle
को ठीक वैसे ही देखा जा सकता है
आपको किसी फ़्रैगमेंट या गतिविधि के Lifecycle
दिखेंगे. इसके अलावा,
NavBackStackEntry
एक LifecycleOwner
है. इसका मतलब है कि आप इसका इस्तेमाल तब कर सकते हैं, जब
LiveData
या लाइफ़साइकल की जानकारी वाले अन्य कॉम्पोनेंट के साथ ऑब्ज़र्विंग की जा रही है, जैसा कि
नीचे दिया गया उदाहरण:
Kotlin
myViewModel.liveData.observe(backStackEntry, Observer { myData -> // react to live data update })
Java
myViewModel.getLiveData().observe(backStackEntry, myData -> { // react to live data update });
जब भी navigate()
को कॉल किया जाता है, तब लाइफ़साइकल की स्थिति अपने-आप अपडेट हो जाती है.
उन डेस्टिनेशन के लिए लाइफ़साइकल स्टेटस जो पिछली गतिविधियों में सबसे ऊपर नहीं हैं
अगर गंतव्य अब भीRESUMED
STARTED
FloatingWindow
डेस्टिनेशन, जैसे कि डायलॉग डेस्टिनेशन या STOPPED
के लिए
नहीं तो.
पिछले गंतव्य पर कोई परिणाम वापस करना
नेविगेशन 2.3 और उसके बाद के वर्शन में, NavBackStackEntry
SavedStateHandle
.
SavedStateHandle
एक की-वैल्यू मैप होता है, जिसे स्टोर और वापस पाने के लिए इस्तेमाल किया जा सकता है
डेटा शामिल है. ये वैल्यू, कॉन्फ़िगरेशन के साथ-साथ प्रोसेस बंद होने के दौरान भी बनी रहती हैं
बदलाव करता है और उसी ऑब्जेक्ट के ज़रिए उपलब्ध रहता है. दिए गए डेटा का इस्तेमाल करके
SavedStateHandle
, एक डेस्टिनेशन से दूसरे डेस्टिनेशन के बीच डेटा को ऐक्सेस और पास किया जा सकता है.
यह विशेष रूप से एक ऐसे तरीके के रूप में उपयोगी है, जिसकी मदद से किसी
डेस्टिनेशन पर क्लिक करें.
डेटा को डेस्टिनेशन B से डेस्टिनेशन A को वापस भेजने के लिए, पहले
डेस्टिनेशन A को सेट अप करें, ताकि वह SavedStateHandle
पर नतीजा सुन सके.
ऐसा करने के लिए, NavBackStackEntry
को
getCurrentBackStackEntry()
एपीआई और फिर LiveData
को observe
SavedStateHandle
की ओर से उपलब्ध कराया गया.
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val navController = findNavController(); // We use a String here, but any type that can be put in a Bundle is supported navController.currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe( viewLifecycleOwner) { result -> // Do something with the result. } }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { NavController navController = NavHostFragment.findNavController(this); // We use a String here, but any type that can be put in a Bundle is supported MutableLiveData<String> liveData = navController.getCurrentBackStackEntry() .getSavedStateHandle() .getLiveData("key"); liveData.observe(getViewLifecycleOwner(), new Observer<String>() { @Override public void onChanged(String s) { // Do something with the result. } }); }
गंतव्य B में, आपको इसके SavedStateHandle
पर परिणाम set
करना होगा
getPreviousBackStackEntry()
एपीआई का इस्तेमाल करके डेस्टिनेशन A.
Kotlin
navController.previousBackStackEntry?.savedStateHandle?.set("key", result)
Java
navController.getPreviousBackStackEntry().getSavedStateHandle().set("key", result);
अगर आपको किसी नतीजे को सिर्फ़ एक बार मैनेज करना है, तो आपको
remove()
SavedStateHandle
पर क्लिक करें. यदि आप
परिणाम के रूप में, LiveData
किसी भी
नए Observer
इंस्टेंस.
डायलॉग डेस्टिनेशन का इस्तेमाल करते समय इन बातों का ध्यान रखें
जब आप किसी ऐसे डेस्टिनेशन पर navigate
पर जाते हैं जहां
NavHost
(जैसे कि कोई <fragment>
मंज़िल), पिछला गंतव्य
इसकी लाइफ़साइकल रुक गई है और LiveData
पर किसी भी कॉलबैक को रोका जा सकता है
SavedStateHandle
की ओर से उपलब्ध कराया गया.
हालांकि, किसी
डायलॉग डेस्टिनेशन,
स्क्रीन पर पिछला डेस्टिनेशन भी दिख रहा है, इसलिए अब भी दिख रहा है
मौजूदा डेस्टिनेशन न होने के बावजूद, STARTED
. इसका मतलब है कि
लाइफ़साइकल वाले तरीकों में getCurrentBackStackEntry()
, जैसे कि
onViewCreated()
, डायलॉग डेस्टिनेशन का NavBackStackEntry
दिखाएगा
कॉन्फ़िगरेशन में बदलाव या मौत और मनोरंजन की प्रोसेस के बाद (जब से
को दूसरे डेस्टिनेशन के ऊपर वापस लाया जाता है). इसलिए, आपको
getBackStackEntry()
अपने गंतव्य के आईडी के साथ यह सुनिश्चित करें कि आप हमेशा सही
NavBackStackEntry
.
इसका मतलब यह भी है कि LiveData
के नतीजे पर सेट किया गया कोई भी Observer
यह तब भी ट्रिगर होता है, जब डायलॉग डेस्टिनेशन स्क्रीन पर मौजूद होते हैं. अगर आपको
परिणाम की जाँच तभी करनी है जब डायलॉग गंतव्य बंद हो और
मौजूदा डेस्टिनेशन बन जाता है, तो आपको पता चलेगा कि
NavBackStackEntry
से जुड़ा Lifecycle
और नतीजा फिर से पाएं
सिर्फ़ तब, जब यह RESUMED
हो जाए.
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val navController = findNavController(); // After a configuration change or process death, the currentBackStackEntry // points to the dialog destination, so you must use getBackStackEntry() // with the specific ID of your destination to ensure we always // get the right NavBackStackEntry val navBackStackEntry = navController.getBackStackEntry(R.id.your_fragment) // Create our observer and add it to the NavBackStackEntry's lifecycle val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_RESUME && navBackStackEntry.savedStateHandle.contains("key")) { val result = navBackStackEntry.savedStateHandle.get<String>("key"); // Do something with the result } } navBackStackEntry.lifecycle.addObserver(observer) // As addObserver() does not automatically remove the observer, we // call removeObserver() manually when the view lifecycle is destroyed viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_DESTROY) { navBackStackEntry.lifecycle.removeObserver(observer) } }) }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); NavController navController = NavHostFragment.findNavController(this); // After a configuration change or process death, the currentBackStackEntry // points to the dialog destination, so you must use getBackStackEntry() // with the specific ID of your destination to ensure we always // get the right NavBackStackEntry final NavBackStackEntry navBackStackEntry = navController.getBackStackEntry(R.id.your_fragment); // Create our observer and add it to the NavBackStackEntry's lifecycle final LifecycleEventObserver observer = new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event.equals(Lifecycle.Event.ON_RESUME) && navBackStackEntry.getSavedStateHandle().contains("key")) { String result = navBackStackEntry.getSavedStateHandle().get("key"); // Do something with the result } } }; navBackStackEntry.getLifecycle().addObserver(observer); // As addObserver() does not automatically remove the observer, we // call removeObserver() manually when the view lifecycle is destroyed getViewLifecycleOwner().getLifecycle().addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event.equals(Lifecycle.Event.ON_DESTROY)) { navBackStackEntry.getLifecycle().removeObserver(observer) } } }); }
ViewModel की मदद से, डेस्टिनेशन के बीच यूज़र इंटरफ़ेस (यूआई) से जुड़ा डेटा शेयर करें
नेविगेशन बैक स्टैक में
NavBackStackEntry
हर डेस्टिनेशन के लिए ही नहीं, बल्कि हर पैरंट नेविगेशन के लिए भी
किसी डेस्टिनेशन की जानकारी देने वाला ग्राफ़. इसकी मदद से आपको
NavBackStackEntry
, जो नेविगेशन ग्राफ़ के दायरे में आता है. नेविगेशन
ग्राफ़ के स्कोप वाला NavBackStackEntry
, ViewModel
को बनाने का तरीका बताता है, जो
एक नेविगेशन ग्राफ़ तक सीमित है. इससे आपको अलग-अलग प्लैटफ़ॉर्म के बीच यूज़र इंटरफ़ेस (यूआई) से जुड़ा डेटा शेयर करने में मदद मिलेगी
ग्राफ़ के डेस्टिनेशन. इस तरह से बनाया गया कोई भी ViewModel
ऑब्जेक्ट तब तक लाइव रहता है, जब तक
संबंधित NavHost
और उसके ViewModelStore
को हटा दिया जाता है या
नेविगेशन ग्राफ़, पिछली गतिविधियों से पॉप-अप हुआ हो.
नीचे दिए गए उदाहरण में, एक रेंज वाले ViewModel
को वापस पाने का तरीका बताया गया है
नेविगेशन ग्राफ़:
Kotlin
val viewModel: MyViewModel by navGraphViewModels(R.id.my_graph)
Java
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph); MyViewModel viewModel = new ViewModelProvider(backStackEntry).get(MyViewModel.class);
अगर नेविगेशन 2.2.0 या इससे पहले के वर्शन का इस्तेमाल किया जा रहा है, तो आपको खुद का नेविगेशन करना होगा इस्तेमाल करने के लिए फ़ैक्ट्री ViewModels के साथ सेव की गई स्थिति, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:
Kotlin
val viewModel: MyViewModel by navGraphViewModels(R.id.my_graph) { SavedStateViewModelFactory(requireActivity().application, requireParentFragment()) }
Java
NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph); ViewModelProvider viewModelProvider = new ViewModelProvider( backStackEntry.getViewModelStore(), new SavedStateViewModelFactory( requireActivity().getApplication(), requireParentFragment())); MyViewModel myViewModel = provider.get(myViewModel.getClass());
ViewModel
के बारे में ज़्यादा जानकारी के लिए, इसे देखें
ViewModel की खास जानकारी.
इनफ़्लेटेड नेविगेशन ग्राफ़ में बदलाव करना
रनटाइम के दौरान, इनफ़्लेट किए गए नेविगेशन ग्राफ़ में डाइनैमिक तौर पर बदलाव किया जा सकता है.
उदाहरण के लिए, अगर आपके पास
BottomNavigationView
जो NavGraph
से जुड़ा होता है, जो
ऐप्लिकेशन शुरू होने पर, NavGraph
चुने गए टैब को निर्देश देता है. हालांकि, आपको
इस व्यवहार को ओवरराइड करने की ज़रूरत, जैसे कि जब कोई उपयोगकर्ता प्राथमिकता तय करती है
ऐप्लिकेशन स्टार्टअप पर लोड होने के लिए पसंदीदा टैब. इसके अलावा, आपका ऐप्लिकेशन शायद
उपयोगकर्ता के पिछले व्यवहार के आधार पर शुरुआती टैब में बदलाव करना ज़रूरी है. आप
इन मामलों में मदद करने के लिए,
NavGraph
.
इस NavGraph
को देखें:
<?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"> <fragment android:id="@+id/home" android:name="com.example.android.navigation.HomeFragment" android:label="fragment_home" tools:layout="@layout/fragment_home" /> <fragment android:id="@+id/location" android:name="com.example.android.navigation.LocationFragment" android:label="fragment_location" tools:layout="@layout/fragment_location" /> <fragment android:id="@+id/shop" android:name="com.example.android.navigation.ShopFragment" android:label="fragment_shop" tools:layout="@layout/fragment_shop" /> <fragment android:id="@+id/settings" android:name="com.example.android.navigation.SettingsFragment" android:label="fragment_settings" tools:layout="@layout/fragment_settings" /> </navigation>
यह ग्राफ़ लोड होने पर, app:startDestination
एट्रिब्यूट तय करता है
कि HomeFragment
दिखाना है. शुरुआती डेस्टिनेशन बदलने के लिए
डाइनैमिक तौर पर, ये काम करें:
- सबसे पहले,
NavGraph
को मैन्युअल तरीके से बढ़ाएं. - शुरुआती डेस्टिनेशन को बदलें.
- आखिर में, ग्राफ़ को
NavController
में मैन्युअल तरीके से अटैच करें.
Kotlin
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController val navGraph = navController.navInflater.inflate(R.navigation.bottom_nav_graph) navGraph.startDestination = R.id.shop navController.graph = navGraph binding.bottomNavView.setupWithNavController(navController)
Java
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager() .findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.bottom_nav_graph); navGraph.setStartDestination(R.id.shop); navController.setGraph(navGraph); NavigationUI.setupWithNavController(binding.bottomNavView, navController);
अब आपका ऐप्लिकेशन शुरू होने पर, HomeFragment
के बजाय ShopFragment
दिखेगा.
डीप लिंक का इस्तेमाल करते समय, NavController
एक बैक स्टैक बनाता है
डीप लिंक डेस्टिनेशन के लिए अपने-आप ट्रिगर हो जाएगा. अगर उपयोगकर्ता
डीप लिंक पर जाता है और फिर पीछे की ओर जाता है.
शुरुआत गंतव्य तक पहुंच सकता है या नहीं.
पिछले उदाहरण में बताई गई तकनीक से यह पक्का होता है कि सही स्टार्ट
डेस्टिनेशन को बनाए गए बैक स्टैक में जोड़ा गया है.
ध्यान दें कि इस तकनीक का इस्तेमाल करने पर, कन्वर्ज़न के अन्य पहलुओं को भी बदला जा सकता है
NavGraph
को ज़रूरत के मुताबिक. ग्राफ़ में सभी बदलाव किए जाने चाहिए
setGraph()
को कॉल करने से पहले, ताकि यह पक्का किया जा सके कि आपका स्ट्रक्चर सही है
इसका इस्तेमाल डीप लिंक हैंडल करते समय, स्टेट को रीस्टोर करते समय, और शुरुआत में ले जाते समय किया जाता है
डेस्टिनेशन (विज्ञापन के लिए सही दर्शक चुनना) की ज़रूरत नहीं है.