Gezinme bileşeni, bunları programatik olarak oluşturma ve etkileşime geçirme satır içi metin ekleyin.
NavHostFragment oluşturma
Tekliflerinizi otomatikleştirmek ve optimize etmek için
NavHostFragment.create()
belirli bir grafik kaynağıyla programatik olarak bir NavHostFragment
oluşturmak için
aşağıdaki örnekte gösterildiği gibi:
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)
ile NavHost
izin verildiğini unutmayın
müdahale sisteminin Geri düğmesine bastığında. Bu davranışı Google Analytics 4'te de
app:defaultNavHost="true"
ekleyerek NavHost
XML. Yaklaşımınızı
özel Geri düğmesi davranışı
ve NavHost
geri düğmesine basılmasını istemiyorsanız
null
- setPrimaryNavigationFragment()
.
NavBackStackEntry kullanarak bir hedefe başvurma
Gezinme 2.2.0'dan başlayarak, istediğiniz zaman
NavBackStackEntry
öğesini çağırarak gezinme yığınındaki herhangi bir hedefe
NavController.getBackStackEntry()
,
hedef kimliği iletir. Arka yığın birden fazla örnek içeriyorsa
belirtilen hedefin getBackStackEntry()
işlevi, en üstteki örneği döndürür
seçeceğim.
Döndürülen NavBackStackEntry
, bir
Lifecycle
, bir
ViewModelStore
ve bir
SavedStateRegistry
teşvik edebilirsiniz. Bu nesneler, arka yığındaki hedefin ömrü boyunca geçerlidir. İlişkili hedef otomatik olarak
Lifecycle
kaldırılır, durum kaydedilmez ve ViewModel
nesneleri temizlenir.
Bu mülkler size bir Lifecycle
ve ViewModel
nesne için bir mağaza sağlar ve
Çevik yaklaşımla
kayıtlı duruma bakılmaksızın
kullandığınız hedef türünden
emin olmanız gerekir. Bu, özellikle paydaşlarla çalışırken
otomatik olarak ilişkilendirilmiş Lifecycle
bulunmayan hedef türleri
(ör. özel hedefler)
Örneğin, NavBackStackEntry
öğesinin Lifecycle
değerini
bir parçanın veya etkinliğin Lifecycle
öğesini gözlemlersiniz. Ayrıca,
NavBackStackEntry
bir LifecycleOwner
değeridir, yani şu durumlarda kullanabilirsiniz:
aşağıdaki örnekteki gibi LiveData
veya yaşam döngüsüne duyarlı diğer bileşenlerle
şu örneği inceleyin:
Kotlin
myViewModel.liveData.observe(backStackEntry, Observer { myData -> // react to live data update })
Java
myViewModel.getLiveData().observe(backStackEntry, myData -> { // react to live data update });
Yaşam döngüsü durumu, navigate()
öğesini her çağırdığınızda otomatik olarak güncellenir.
Arka yığının en üstünde olmayan hedeflerin yaşam döngüsü durumları
Hedefler hala altında görünür durumdaysa RESUMED
- STARTED
arasında
FloatingWindow
hedefi (ör. iletişim kutusu hedefi veya STOPPED
)
aksi takdirde.
Bir sonucu önceki Hedefe döndürme
Gezinme 2.3 ve sonraki sürümlerde NavBackStackEntry
,
SavedStateHandle
SavedStateHandle
, verileri depolamak ve almak için kullanılabilen bir anahtar/değer eşlemesidir
dışı verilerdir. Bu değerler, yapılandırma dahil olmak üzere işlem ölümü yoluyla korunur.
ve aynı nesne
üzerinden erişilebilir durumda kalmasını sağlar. Verilen
SavedStateHandle
, verilere erişebilir ve hedefler arasında veri aktarabilirsiniz.
Bu, özellikle bir kullanıcıdan gelen verileri geri alma mekanizması olarak
başka bir hedef belirleyebilirsiniz.
Verileri Hedef B'den Hedef A'ya geri aktarmak için önce
sonucu SavedStateHandle
cihazında dinlemek için Hedef A'yı ayarlayın.
Bunu yapmak için şunu kullanarak NavBackStackEntry
öğesini alın:
getCurrentBackStackEntry()
API ve ardından observe
LiveData
sağlayan: 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. } }); }
Hedef B'de sonucu şunun SavedStateHandle
: set
getPreviousBackStackEntry()
API'yi kullanarak A Hedefi.
Kotlin
navController.previousBackStackEntry?.savedStateHandle?.set("key", result)
Java
navController.getPreviousBackStackEntry().getSavedStateHandle().set("key", result);
Bir sonucu yalnızca bir kez işlemek isterseniz
remove()
SavedStateHandle
düğmesine basın. Etiketteki
LiveData
, son sonucu herhangi bir sonuca döndürmeye devam eder
yeni Observer
örneği.
İletişim kutusu hedeflerini kullanırken dikkat edilmesi gereken noktalar
Tam görünümünü alan bir hedefe navigate
gittiğinizde
NavHost
(<fragment>
hedefi gibi), önceki hedef
yaşam döngüsü durduğu için LiveData
sağlayan: SavedStateHandle
.
Ancak bir
iletişim kutusu hedefi,
ekranda da görünür ve böylece
Şu anki hedef olmamasına rağmen STARTED
. Bu, paydaşlara
Aşağıdaki gibi yaşam döngüsü yöntemlerinden getCurrentBackStackEntry()
onViewCreated()
, iletişim kutusu hedefinin NavBackStackEntry
değerini döndürür
veya yapılandırma değişikliğinden ya da ölüm ve yeniden oluşturma işlemlerinden sonra (iletişim kutusu
diğer hedefin üzerine geri yüklenir). Bu nedenle
getBackStackEntry()
Her zaman doğru
NavBackStackEntry
.
Bu aynı zamanda, LiveData
sonucu için ayarladığınız tüm Observer
iletişim kutusu hedefleri ekrandayken bile tetiklenir. Şu durumda:
yalnızca iletişim kutusu hedefi kapatıldığında ve yeni iletişim kutusu seçildiğinde
temel hedef mevcut hedef haline gelirse,
Lifecycle
, NavBackStackEntry
ile ilişkilendirilir ve sonucu alır
yalnızca RESUMED
olduğunda.
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 ile hedefler arasında kullanıcı arayüzüyle ilgili verileri paylaşma
Gezinme geri yığını,
NavBackStackEntry
Yalnızca her bir hedef için değil, aynı zamanda her üst gezinme için
tek bir hedefi içeren grafiktir. Bu işlem,
Gezinme grafiğine dahil edilen NavBackStackEntry
. Gezinme
grafik kapsamlı NavBackStackEntry
, aşağıdaki gibi görünen ViewModel
için
kullanıcı arayüzüyle ilgili verileri Google Haritalar ve Google Earth arasındaki
hedefler. Bu şekilde oluşturulan tüm ViewModel
nesneleri
ilişkilendirilmiş NavHost
ve ViewModelStore
öğeleri temizlenir veya
gezinme grafiği arka yığından atılır.
Aşağıdaki örnekte,ViewModel
gezinme grafiği:
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);
Navigasyon 2.2.0 veya daha eski bir sürümü kullanıyorsanız kendi fabrika ayarı ViewModels ile Kayıtlı Durum, aşağıdaki örnekte gösterildiği gibi:
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
hakkında daha fazla bilgi için bkz.
ViewModel'e Genel Bakış.
Şişmiş gezinme grafiklerini değiştirme
Şişmiş bir gezinme grafiğini çalışma zamanında dinamik olarak değiştirebilirsiniz.
Örneğin,
BottomNavigationView
web sitesinin varsayılan hedefi olan NavGraph
öğesine bağlı
NavGraph
, uygulama başlatılırken seçilen sekmeyi belirtir. Ancak,
gerektiğinde bu davranışı geçersiz kılmanız gerekir (örneğin, bir kullanıcı tercihinin,
Uygulama başlangıcında yüklenmesi tercih edilen bir sekme olmalıdır. Alternatif olarak uygulamanız
kullanıcı davranışına dayalı olarak başlangıç sekmesini değiştirmesi
gerektiğini unutmayın. Şunları yapabilirsiniz:
bu durumlarda, sitenin varsayılan hedefini dinamik olarak
NavGraph
.
Bu NavGraph
türünü düşünün:
<?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>
Bu grafik yüklendiğinde app:startDestination
özelliği,
HomeFragment
tarihinin görüntülenmesine. Başlangıç hedefini geçersiz kılmak için
dinamik olarak şunları yapın:
- İlk olarak,
NavGraph
değerini manuel olarak şişirin. - Başlangıç hedefini geçersiz kılın.
- Son olarak, grafiği
NavController
öğesine manuel olarak ekleyin.
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);
Artık uygulamanız başlatıldığında HomeFragment
yerine ShopFragment
gösterilir.
Derin bağlantılar kullanılırken NavController
, bir arka yığın oluşturur
otomatik olarak oluşturulur. Kullanıcı
gittiğinde derin bağlantıya gider ve geri giderse
bir noktada başlar. Başlangıç hedefini
tekniği kullanarak, doğru başlangıcı
oluşturulan arka yığınına eklenir.
Bu tekniğin, aynı zamanda ekibinizin
bir parçası olan diğer unsurların da geçersiz kılınmasına
NavGraph
değerini gerektiği gibi değiştirin. Grafikte tüm değişikliklerin yapılması gerekir
önceki önce setGraph()
Derin bağlantılar işlenirken, durumu geri yüklerken ve başa dönerken kullanılır
hedefi belirir.