2026'da Jetpack Navigation Compose: Type-Safe Navigasyon ve Mülakat Soruları

Type-safe navigasyon, gelişmiş desenler ve Android geliştiricileri için mülakat soruları içeren kapsamlı Jetpack Navigation Compose rehberi.

2026'da Jetpack Navigation Compose - Android'de type-safe navigasyon

Navigasyon, her mobil uygulamanın temel yapı taşlarından birini oluşturur. Android ekosisteminde Jetpack Navigation Compose, 2026 yılında type-safe navigasyon için tam destek sunarak önemli bir evrim geçirmiştir. Bu rehber, Compose uygulamalarında navigasyon implementasyonuna yönelik güncel yaklaşımları sunmakta ve Android Developer pozisyonları için mülakat hazırlığı sağlamaktadır.

Navigation 2.8.0 sürümünden itibaren, Compose navigasyonu için Kotlin DSL tamamen tipli argüman geçişini desteklemekte, manuel string ayrıştırma ihtiyacını ortadan kaldırmakta ve çalışma zamanı hatalarını önemli ölçüde azaltmaktadır.

Jetpack Navigation Compose Temelleri

Jetpack Navigation Compose, navigasyon grafiğinin doğrudan Kotlin kodunda deklaratif olarak tanımlanmasını sağlar. XML tabanlı geleneksel yaklaşımın aksine, tüm navigasyon grafiği programatik olarak tanımlanır ve bu durum Compose ile daha iyi entegrasyon ve daha fazla esneklik sunar.

Temel kurulum, NavHost ve bireysel destinasyonların tanımlanmasını gerektirir:

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    
    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(
                onNavigateToDetails = { id ->
                    navController.navigate("details/$id")
                }
            )
        }
        composable(
            route = "details/{itemId}",
            arguments = listOf(
                navArgument("itemId") { type = NavType.StringType }
            )
        ) { backStackEntry ->
            val itemId = backStackEntry.arguments?.getString("itemId")
            DetailsScreen(itemId = itemId)
        }
    }
}

Yukarıdaki örnek, string tabanlı argümanlarla geleneksel yaklaşımı göstermektedir. İşlevsel olmasına rağmen, manuel ayrıştırma gerektirmekte ve yazım hatalarına açık bulunmaktadır.

Kotlin Serialization ile Type-Safe Navigasyon

Type-safe navigasyonun tanıtılması, manuel argüman yönetimiyle ilgili sorunları ortadan kaldırmaktadır. Kotlin Serialization entegrasyonu sayesinde, destinasyonlar tam tip desteğiyle data class olarak tanımlanmaktadır.

kotlin
@Serializable
object Home

@Serializable
data class Details(val itemId: String)

@Serializable
data class Profile(val userId: Int, val showSettings: Boolean = false)

@Composable
fun TypeSafeNavigation() {
    val navController = rememberNavController()
    
    NavHost(
        navController = navController,
        startDestination = Home
    ) {
        composable<Home> {
            HomeScreen(
                onNavigateToDetails = { id ->
                    navController.navigate(Details(itemId = id))
                }
            )
        }
        composable<Details> { backStackEntry ->
            val details: Details = backStackEntry.toRoute()
            DetailsScreen(itemId = details.itemId)
        }
        composable<Profile> { backStackEntry ->
            val profile: Profile = backStackEntry.toRoute()
            ProfileScreen(
                userId = profile.userId,
                showSettings = profile.showSettings
            )
        }
    }
}

Bu yaklaşımın temel avantajları arasında derleme zamanı tip doğrulaması, otomatik argüman serileştirme ve yanlış rota adlarıyla ilgili hataların eliminasyonu yer almaktadır.

İç İçe Navigasyon Grafikleri

Daha büyük uygulamalarda, navigasyonun iç içe grafiklere organize edilmesi kod okunabilirliğini artırır ve işlevselliğin modülerleştirilmesini sağlar. Her uygulama modülü kendi navigasyon alt grafiğini tanımlayabilir.

kotlin
@Serializable
object AuthGraph

@Serializable
object Login

@Serializable
object Register

@Serializable
object ForgotPassword

fun NavGraphBuilder.authNavGraph(navController: NavController) {
    navigation<AuthGraph>(startDestination = Login) {
        composable<Login> {
            LoginScreen(
                onNavigateToRegister = {
                    navController.navigate(Register)
                },
                onNavigateToForgotPassword = {
                    navController.navigate(ForgotPassword)
                }
            )
        }
        composable<Register> {
            RegisterScreen(
                onRegistrationComplete = {
                    navController.popBackStack(Login, inclusive = true)
                    navController.navigate(Home)
                }
            )
        }
        composable<ForgotPassword> {
            ForgotPasswordScreen(
                onPasswordReset = {
                    navController.popBackStack()
                }
            )
        }
    }
}

İç içe grafikleri, belirli bir modüle özgü navigasyon mantığının kapsüllenmesini sağlar ve bu durum özellikle çok modüllü mimaride faydalıdır.

Deep link'ler, bir uygulamanın belirli bir ekranının harici bir kaynaktan doğrudan açılmasına olanak tanır. Navigation Compose, deep link'leri deklaratif yapılandırma aracılığıyla desteklemektedir.

kotlin
@Serializable
data class Product(
    val productId: String,
    val source: String? = null
)

NavHost(
    navController = navController,
    startDestination = Home
) {
    composable<Product>(
        deepLinks = listOf(
            navDeepLink<Product>(
                basePath = "https://example.com/product"
            )
        )
    ) { backStackEntry ->
        val product: Product = backStackEntry.toRoute()
        ProductScreen(
            productId = product.productId,
            source = product.source
        )
    }
}

AndroidManifest.xml yapılandırması, sistem düzeyinde deep link desteği için gerekli olmaya devam etmektedir:

xml
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="example.com"
            android:pathPrefix="/product" />
    </intent-filter>
</activity>

Etkin navigasyon durum yönetimi, NavBackStackEntry yaşam döngüsünün ve durum koruma mekanizmalarının anlaşılmasını gerektirir. SavedStateHandle, yapılandırma değişikliklerinden kurtulan verilerin saklanmasını sağlar.

kotlin
@HiltViewModel
class ProductViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    
    private val productRoute: Product = savedStateHandle.toRoute()
    
    val productId: String = productRoute.productId
    
    private val _uiState = MutableStateFlow(ProductUiState())
    val uiState: StateFlow<ProductUiState> = _uiState.asStateFlow()
    
    init {
        loadProduct(productId)
    }
    
    private fun loadProduct(id: String) {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true) }
            // Fetch product data
        }
    }
}

Hilt entegrasyonu, SavedStateHandle'ın ViewModel'e otomatik enjeksiyonunu sağlar ve bu durum navigasyon argümanlarına type-safe erişim imkanı sunar.

Geçiş Animasyonları

Navigation Compose, ekranlar arasında özel geçiş animasyonları için destek sunmaktadır. Animasyonlar, bireysel destinasyon düzeyinde veya tüm NavHost için global olarak tanımlanabilir.

kotlin
NavHost(
    navController = navController,
    startDestination = Home,
    enterTransition = {
        slideIntoContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Start,
            animationSpec = tween(300)
        )
    },
    exitTransition = {
        slideOutOfContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.Start,
            animationSpec = tween(300)
        )
    },
    popEnterTransition = {
        slideIntoContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.End,
            animationSpec = tween(300)
        )
    },
    popExitTransition = {
        slideOutOfContainer(
            towards = AnimatedContentTransitionScope.SlideDirection.End,
            animationSpec = tween(300)
        )
    }
) {
    // Destinations
}

Koşullu Navigasyon ve Guard'lar

Koşullu navigasyonun implementasyonu, örneğin korumalı ekranlara erişmeden önce kimlik doğrulama durumunun kontrol edilmesi, uygun mimariyi gerektirir.

kotlin
@Composable
fun AppNavigation(
    isAuthenticated: Boolean,
    onAuthRequired: () -> Unit
) {
    val navController = rememberNavController()
    
    LaunchedEffect(isAuthenticated) {
        if (!isAuthenticated) {
            navController.navigate(Login) {
                popUpTo(navController.graph.startDestinationId) {
                    inclusive = true
                }
            }
        }
    }
    
    NavHost(
        navController = navController,
        startDestination = if (isAuthenticated) Home else Login
    ) {
        composable<Home> {
            HomeScreen()
        }
        composable<Login> {
            LoginScreen(
                onLoginSuccess = {
                    navController.navigate(Home) {
                        popUpTo(Login) { inclusive = true }
                    }
                }
            )
        }
    }
}

Compose uygulamalarında navigasyon testi, uygun test ortamı hazırlığını gerektirir. navigation-testing kütüphanesi, navigasyon davranışının doğrulanması için araçlar sağlamaktadır.

kotlin
class NavigationTest {
    
    @get:Rule
    val composeTestRule = createComposeRule()
    
    private lateinit var navController: TestNavHostController
    
    @Before
    fun setup() {
        composeTestRule.setContent {
            navController = TestNavHostController(LocalContext.current)
            navController.navigatorProvider.addNavigator(
                ComposeNavigator()
            )
            AppNavigation(navController = navController)
        }
    }
    
    @Test
    fun navigateToDetails_displaysCorrectScreen() {
        composeTestRule.onNodeWithText("View Details").performClick()
        
        val currentRoute = navController.currentBackStackEntry?.toRoute<Details>()
        assertNotNull(currentRoute)
        assertEquals("expected-id", currentRoute?.itemId)
    }
}

Android mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

Mülakat Soruları: Jetpack Navigation Compose

Aşağıda, Android Developer pozisyonları için yapılan mülakatlarda Compose'da navigasyon konusunda sorulan tipik sorular sunulmaktadır.

Soru: Compose'da string tabanlı navigasyon ile type-safe navigasyon arasındaki temel farklar nelerdir?

String tabanlı navigasyon, rotaların string olarak manuel tanımlanmasını ve argümanların NavBackStackEntry'den ayrıştırılmasını gerektirir. Yazım hatalarına açıktır ve derleme zamanı tip doğrulaması sunmamaktadır. Type-safe navigasyon, @Serializable anotasyonlu data class'ları destinasyon olarak kullanır; tam tip doğrulaması, otomatik argüman serileştirme ve deserileştirme sağlar ve yanlış rota adlarıyla ilgili hataları ortadan kaldırır.

Soru: Kimlik doğrulama durumuna dayalı koşullu navigasyon nasıl implemente edilir?

Koşullu navigasyon, kimlik doğrulama durumunun LaunchedEffect içinde gözlemlenmesi veya derivedStateOf kullanılması yoluyla implemente edilir. Kimlik doğrulama durumu değiştiğinde, navController navigasyon yığınını temizlemek için inclusive = true ile popUpTo kullanarak programatik olarak uygun destinasyona yönlendirir.

Soru: popBackStack() ve navigateUp() arasındaki farkı açıklayın.

popBackStack() metodu, mevcut destinasyonu koşulsuz olarak navigasyon yığınından kaldırır. navigateUp() metodu, deep link'ler ve üst graflar tarafından tanımlanan navigasyon yapısına saygı gösterir ve uygulama deep link aracılığıyla başlatıldıysa potansiyel olarak mevcut grafın dışındaki bir destinasyona yönlendirir.

Soru: Compose'da navigasyon sırasında ekran durumu nasıl korunur?

Ekran durumu, basit değerler için rememberSaveable kullanılarak, karmaşık veriler için ViewModel'de SavedStateHandle kullanılarak ve uygun NavBackStackEntry yönetimiyle doğru NavHost yapılandırması aracılığıyla korunur. Ek olarak, NavOptions'da saveState ve restoreState mekanizması kullanılabilir.

Soru: Çok modüllü bir uygulamada navigasyon organizasyonu için en iyi pratikler nelerdir?

Çok modüllü mimaride, her işlevsel modül kendi destinasyonlarını public data class'lar olarak ve navigasyon alt grafiğini ekleyen bir NavGraphBuilder extension function tanımlar. App modülü, tüm alt grafikleri ana NavHost'ta birleştirir. Destinasyonlar modülün public API'si aracılığıyla açığa çıkarılırken, ekran implementasyonları private kalır.

Sonuç

2026 yılında Jetpack Navigation Compose, Android uygulamalarında navigasyon implementasyonu için olgun ve kapsamlı bir araç seti sunmaktadır. Type-safe navigasyonun tanıtılması, tip güvenliğini önemli ölçüde artırmakta ve çalışma zamanı hatalarını azaltmaktadır. İç içe graflar, deep link'ler ve geçiş animasyonları gibi gelişmiş desenlerin anlaşılması, Android Developer pozisyonları için mülakat hazırlığının kritik bir unsurunu oluşturmaktadır.

Çeşitli navigasyon senaryolarının düzenli olarak pratik edilmesi ve Navigation Compose kütüphanesinin iç mekanizmalarının derinlemesine anlaşılması, hem günlük çalışmada hem de teknik mülakatlarda sorunların etkin çözümüne hazırlamaktadır.

Günün meydan okuması

Android kodundaki hatayı bulabilir misin?

Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Anthony Fillion-Maillet

Yazan:

Anthony Fillion-Maillet

SharpSkill kurucusu

10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.

1 Eylül 2026 tarihinde güncellendi

Etiketler

#android
#jetpack compose
#navigation
#kotlin
#type-safe

Paylaş

İlgili makaleler