NavController, Navigation Compose kitaplığının Android uygulamalarında navigasyon yığınını ve back stack durumunu yöneten merkezi bileşenidir. NavController aracılığıyla ekranlar arası geçişler, önceki sayfalara dönüş ve rotalar arasında veri aktarımı gerçekleştirilir. Android Developers (2025)'e göre, NavController birden fazla ekrana sahip her Compose uygulamasının zorunlu bir öğesidir. Denetleyici rememberNavController() ile oluşturulur, NavHost'a iletilir ve kompozisyonun herhangi bir noktasından navigate() çağırmak için kullanılabilir. Yerleşik SavedStateHandle desteği, yeniden yapılandırma sırasında ViewModel durumunu otomatik olarak kaydeder.
Önemli Noktalar
NavController, Navigation Compose kitaplığından Compose uygulamaları için navigasyon denetleyicisini uygulayan bir sınıftır. NavController, NavBackStackEntry yığınını yönetir; her giriş rota, argümanlar ve ekran durumunu içerir. Denetleyici temel navigasyon işlemlerini destekler: geçiş, dönüş, değiştirme ve temizlik.
Navigasyonun FragmentManager veya Intent ile yapıldığı View sisteminin aksine, NavController yalnızca Compose bağlamında çalışır. Back stack, Fragment yığını yerine NavDestination grafiği olarak depolanır. Bu, Fragment oluşturma ve yok etme yükünü ortadan kaldırır ve testi basitleştirir — NavController, TestNavHostController aracılığıyla mock'lanabilir.
NavController, NavHost ile yakından ilişkilidir — grafikten mevcut ekranı oluşturan bir kapsayıcı. NavHost olmadan, NavController composable işlevleri görüntüleyemez ancak yığını yönetme yeteneğini korur. Tipik bir mimaride, NavController Activity veya ana composable düzeyinde oluşturulur ve parametreler aracılığıyla kompozisyon ağacında aşağı iletilir.
Google'a göre, NavController birkaç büyük sürümden geçti. Sürüm 2.8.0 Type-Safe Navigation'ı ekledi, sürüm 2.9.0 predictive back gesture (Android 14+) desteğini ekledi. Denetleyici, Material3 Scaffold ve BottomNavigation ile uyumludur. Çok modüllü projeler için NavController, DI (Hilt/Koin) veya yapıcı parametreleri aracılığıyla iletilir.
NavController, composable işlevi rememberNavController() aracılığıyla oluşturulur. İşlev, mevcut composable'ın yaşam döngüsüne bağlı bir NavHostController (NavController'ın bir alt sınıfı) örneği döndürür. Kompozisyondan çıkıldığında, denetleyici temizlenir. Yeniden yapılandırma sırasında denetleyiciyi korumak için rememberSaveable veya ViewModel kullanın.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "main"
) {
composable("main") { MainScreen(navController) }
composable("details") { DetailsScreen(navController) }
}
}
NavController yapılandırması şunları içerir: NavHostController (ana), TestNavHostController (test) ve ScopedNavController (iç içe grafikler için alt). BottomNavigation için NavController tüm uygulama için tek olmalıdır — her sekmede yeni bir denetleyici oluşturmak yığın kaybına yol açar. Denetleyiciyi iç içe ekranlara iletmek için okunabilirliği korumak adına CompositionLocalProvider yerine bir işlev parametresi kullanın.
Navigasyon testi için compose-test-rule ile TestNavHostController kullanın. Denetleyici, başlangıç rotasını ayarlamaya ve navigate()'in beklenen geçişi tetiklediğini doğrulamaya olanak tanır. NavController'ı test etmek için emülatör gerekmez — Compose Test Semantics eşleştiricileriyle çalışır.
navigate(route: String) yöntemi, NavController'daki birincil navigasyon mekanizmasıdır. Bir rota dizesi, isteğe bağlı NavOptions ve Navigator.Extras kabul eder. NavOptions, geçiş davranışını kontrol eder: launchSingleTop (yığında rotayı çoğaltma), popUpTo (bir rotaya kadar yığını temizleme), restoreState (önceki durumu geri yükleme).
NavOptions, oluşturucu sözdizimiyle (NavOptionsBuilder) ayarlanır. Ana parametreler: popUpTo (rota + inclusive/saveState), launchSingleTop (Boolean, true — çoğaltma oluşturma), restoreState (dönüşte durumu geri yükleme). popUpTo olmadan, her navigate() yığına bir giriş ekler, bu da back stack birikmesine ve Back düğmesinin yanlış davranmasına yol açar.
navController.navigate("profile/42") {
popUpTo("main") { saveState = true }
launchSingleTop = true
restoreState = true
}
Navigator.Extras, rotanın parçası olmayan ek verileri (animasyon için paylaşılan öğeler, Intent bayrakları, Pac-Man paketi) iletmeye olanak tanır. Extras nadiren kullanılır — esas olarak Accompanist Animation veya özel Navigator ile entegrasyon için. Çoğu senaryo için bir rota dizesi ve NavOptions yeterlidir.
popBackStack(), önceki ekrana dönme yöntemidir. Argümansız, yığının en üstündeki girişi kaldırır ve başarılı olursa true döndürür. Yığın boşsa, yöntem false döndürür ve Activity kapanır (super.onBackPressed()'e benzer).
Aşırı yüklenmiş sürüm popBackStack(route: String, inclusive: Boolean), belirtilen rotaya kadar tüm girişleri kaldırır. inclusive = true ise, belirtilen rotanın kendisi de kaldırılır. Yöntem Boolean döndürür — girişler bulunup kaldırıldıysa true. inclusive sürümü, yetkilendirme veya sipariş tamamlamadan sonra “kök ekrana çıkış” senaryoları için kullanışlıdır.
| Yöntem | Açıklama | Örnek |
|---|---|---|
| popBackStack() | Bir ekran geri dön | navController.popBackStack() |
| popBackStack(route, false) | route'a kadar temizle (route kalır) | popBackStack(“home”, false) |
| popBackStack(route, true) | route dahil temizle | popBackStack(“home”, true) |
| navigate(route) { popUpTo(route) { inclusive = true } } | Tam temizlikle gezin | navigate(“login”) { popUpTo(0) { inclusive = true } } |
Sistem Geri düğmesini (donanım geri düğmesi) işlemek için Compose'dan BackHandler kullanın. BackHandler, enabled ve onBack (basıldığında çağrılan geri çağrı) kabul eder. Android 14+ için, NavController sürüm 2.9.0'dan itibaren entegre edilen PredictiveBackGesture kullanılır. Predictive back, dönüş önizleme animasyonu ekler.
SavedStateHandle, navigasyon ve yeniden yapılandırma sırasında ViewModel durumunu korumak için bir mekanizmadır. NavController, her NavBackStackEntry için otomatik olarak SavedStateHandle sağlar. SavedStateHandle aracılığıyla ViewModel ekran durumunu depolar ve dönüşte geri yükler (restoreState = true).
Navigation Compose'da SavedStateHandle, ViewModel ile birlikte kullanılır: ViewModel, backStackEntry'den iletilen SavedStateHandle aracılığıyla başlatılır. Başka bir ekrana gidip dönüldüğünde (restoreState ile), ViewModel yeniden oluşturulmak yerine kaydedilen durumu alır. Bu, veri girişi, filtreler veya kaydırma içeren ekranlar için kritiktir.
class ProfileViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val userId: String = savedStateHandle.get<String>("userId") ?: ""
var searchQuery by savedStateHandle.getStateFlow("search", "")
.collectAsState()
}
SavedStateHandle, ilkel türleri, String, Bundle ve Parcelable'ı destekler. Karmaşık nesneler için yalnızca kimlikleri kaydedin ve tam verileri depodan yükleyin. SavedStateHandle sınırı yaklaşık 1 MB'dır, aşılması TransactionTooLargeException'a neden olur. Büyük hacimler için handle'da kaydetmek yerine Room veya DataStore kullanın.
Önemli: SavedStateHandle yalnızca NavOptions'da restoreState = true kullanıldığında durumu korur. restoreState belirtilmezse, dönüşte ViewModel varsayılan değerlerle yeniden oluşturulur. restoreState ile BottomNavigation geçişi için NavController her sekmenin durumunu korur ve yeniden seçimde geri yükler.
currentBackStackEntryAsState(), State<NavBackStackEntry?> döndüren ve mevcut rota her değiştiğinde güncellenen bir işlevdir. Bu, navigasyonla UI senkronizasyonunun birincil mekanizmasıdır: BottomNavigation aktif öğeyi vurgular, Toolbar başlığı günceller, Drawer geçişte kapanır.
İşlev, snapshotFlow ve collectAsState aracılığıyla çalışır: back stack değiştiğinde Compose, abone olunan öğeleri yeniden oluşturur. Önemli: currentBackStackEntryAsState() yalnızca geçiş animasyonu tamamlandıktan sonra güncellenir. Anlık güncellemeler için, navigate() ile eşzamanlı olarak değişen ancak durumu desteklemeyen currentDestination'ı kullanın.
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
Text(
text = when (currentRoute) {
"home" -> "Home"
"profile" -> "Profile"
else -> ""
}
)
Mevcut rotanın argümanlarına erişmek için navBackStackEntry?.arguments kullanın. Bu, BottomNavigation'da kullanışlıdır: selectedItem, currentRoute'a göre hesaplanır. Navigasyon hata ayıklaması için her geçişi günlüğe kaydeden NavController.addOnDestinationChangedListener() kullanın. Üretimde, çok sayıda composable içinde aboneliklerden kaçının — ViewModel'de tek bir kaynak oluşturun ve State'i UI'a iletin.
Sıkça Sorulan Sorular
Teknik olarak evet, ancak önerilmez. Tek bir NavController tutarlı back stack sağlar ve hata ayıklamayı basitleştirir. Birden fazla denetleyici yalnızca ayrı navigasyona sahip iç içe grafikler için haklıdır (örneğin, kendi yığınına sahip modal bottom sheet).
NavController'ı ViewModel'e yapıcı veya DI aracılığıyla iletin. Ancak, NavController'ın kendisi yerine yalnızca geri çağrı işlevlerini (onNavigate, onBack) iletmek daha iyidir — bu testi basitleştirir. Olaylar için ViewModel'de Channel<NavEvent> kullanın ve UI'da toplayın.
Sorun yaşam döngüsündedir: NavController henüz başlatılmamışsa (NavHost oluşturulmamışsa), navigate() yoksayılır. Veri yüklemesinden sonra navigasyonu çağırmak için rastgele yaşam döngüsüne sahip bir coroutine içinde değil, LaunchedEffect kullanın.
navController.navigate(“hedef”) { popUpTo(0) { inclusive = true } } çağırın. popUpTo(0) parametresi yığını tamamen temizler, inclusive = true başlangıç girişini de kaldırır. launchSingleTop = true bayrağı yinelenen rotaları önler.
NavHostController, NavHost için ek yöntemlere (örneğin, setOnBackStackChangedListener) sahip NavController'ın bir alt sınıfıdır. NavController, programatik yığın yönetimi için NavHost dışında kullanılabilen temel sınıftır. Çoğu durumda NavHostController kullanılır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun