Navigation Component — какво е това, NavHost и Navigation Graph

Автор: IT Sectr Публикувано: 2026-02-22 Време за четене: 7 мин

Navigation Component — библиотека на Android Jetpack за реализиране на навигация между екрани на приложението. Компонентът централизира управлението на стека от фрагменти, дълбоки връзки и предаване на аргументи. Част е от Jetpack от 2018 г. и се препоръчва от Google за всички нови проекти. Прочетете повече в официалното ръководство на Google.

Основни точки

  • Navigation Component — Jetpack библиотека за централизирана навигация между Android екрани
  • NavGraph — XML ресурс, описващ всички екрани и връзките между тях
  • NavHostFragment — контейнер в layout на Activity, показващ текущия навигационен екран
  • NavController — обект за управление на навигация: navigate, popBackStack, navigateUp
  • Safe Args — Gradle плъгин за типобезопасно предаване на аргументи между екрани

Какво е Navigation Component?

Navigation Component — Android Jetpack библиотека (androidx.navigation), предоставяща унифициран API за навигация. Включва три ключови елемента: Navigation Graph (навигационен граф), NavHostFragment (контейнер за екрани) и NavController (контролер на преходи). Компонентът автоматично управлява back stack и поддържа deep links.

Преди Navigation Component разработчиците управляваха фрагменти ръчно чрез FragmentManager. Това водеше до фрагментиран код: всеки екран имаше свои правила за навигация, състоянията на back stack се различаваха, deep links изискваха отделна реализация. Navigation Component унифицира тези сценарии. Според Google (2026), библиотеката е инсталирана в 90% от новите Android проекти.

Navigation Component се интегрира с други Jetpack библиотеки: LiveData, ViewModel, Material Design. Поддържа както XML фрагменти, така и Jetpack Compose чрез разширението navigation-compose. Стабилна версия — 2.8.x (2025), минимална Android версия — API 14.

NavGraph — XML ресурс (res/navigation/nav_graph.xml), определящ всички екрани на приложението и връзките между тях. Всеки екран е възел (destination), който може да бъде Fragment, Activity или Composable. Връзките между възлите са action, които задават посоката на преход.

xml

<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"
    app:startDestination="@+id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name=".HomeFragment"
        android:label="Начало"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home_to_detail"
            app:destination="@+id/detailFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name=".DetailFragment"
        android:label="Детайли"
        tools:layout="@layout/fragment_detail">
        <argument android:name="itemId"
            app:argType="integer"
            android:defaultValue="0" />
    </fragment>
</navigation>

Атрибутът startDestination задава първия екран, показван при стартиране. Action определя целевия destination и опционални анимации. Аргументите (argument) описват параметрите, предавани на екрана — тип и стойност по подразбиране.

NavHostFragment — контейнер, който се поставя в layout на Activity и показва текущия навигационен екран. NavHostFragment автоматично сменя фрагменти при извикване на NavController.navigate(). NavController — обект, управляващ навигацията: преход, връщане, проверка на текущия маршрут.

kotlin
// Layout Activity: activity_main.xml
// <androidx.fragment.app.FragmentContainerView
//     android:id="@+id/nav_host_fragment"
//     android:name="androidx.navigation.fragment.NavHostFragment"
//     app:navGraph="@navigation/nav_graph"
//     app:defaultNavHost="true" />

class MainActivity : AppCompatActivity() {

    private val navController by lazy {
        (findViewById<NavHostFragment>(R.id.nav_host_fragment))
            .navController
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // NavigationUI свързва NavController с AppBar
        setupActionBarWithNavController(navController)
    }

    // Преход към екрана с детайли
    fun openDetail(itemId: Long) {
        val bundle = Bundle().apply {
            putLong("itemId", itemId)
        }
        navController.navigate(R.id.action_home_to_detail, bundle)
    }

    override fun onSupportNavigateUp() = 
        navController.navigateUp() || super.onSupportNavigateUp()
}

app:defaultNavHost="true" — важен атрибут: прихваща системния бутон „Назад" и предава управлението на NavController. NavigationUI — помощна програма за свързване на NavController с AppBar, BottomNavigationView, NavigationDrawer. setupActionBarWithNavController активира стрелката „Нагоре" на вложени екрани.

Navigation Component поддържа персонализирани анимации на преходи, задавани в action или програмно. Анимациите се определят от четири атрибута: enterAnim (появяване на нов екран), exitAnim (изчезване на текущия), popEnterAnim (появяване при връщане) и popExitAnim (изчезване при връщане).

xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
        android:duration="300" />
</set>

// Програмен преход с анимация
val navOptions = NavOptions.Builder()
    .setEnterAnim(R.anim.slide_in_right)
    .setExitAnim(R.anim.slide_out_left)
    .setPopEnterAnim(R.anim.slide_in_left)
    .setPopExitAnim(R.anim.slide_out_right)
    .build()

navController.navigate(R.id.detailFragment, args, navOptions)

Анимациите работят с Fragment на ниво FragmentTransaction. За Jetpack Compose анимациите се задават чрез NavOptionsCompat с използване на Compose Animation. Navigation Component не налага ограничения върху типа анимация — поддържа translate, scale, alpha и техните комбинации.

Safe Args: типобезопасни аргументи

Safe Args — Gradle плъгин за типобезопасно предаване на данни между екрани. Плъгинът анализира NavGraph, генерира класове Directions и Args с конкретни типове полета. На етап компилация се проверява съответствието на типовете — грешка MissingArgumentException се открива преди стартиране на приложението.

kotlin
// build.gradle (module)
plugins {
    id 'androidx.navigation.safeargs.kotlin'
}

// Safe Args генерира: DetailFragmentArgs, HomeFragmentDirections
// Използване в HomeFragment:
val action = HomeFragmentDirections
    .actionHomeToDetail(itemId = 42L)
findNavController().navigate(action)

// Използване в DetailFragment:
private val args: DetailFragmentArgs by navArgs()
// args.itemId има тип Long, null не може да бъде предаден

override fun onViewCreated(...) {
    super.onViewCreated(...)
    loadItem(args.itemId)
}

navArgs() — Kotlin делегат за получаване на аргументи във Fragment или Activity. Плъгинът поддържа примитиви, низове, Parcelable, Serializable, Enum и масиви. За сложни обекти използвайте предаване на ID със зареждане от ViewModel или база данни.

Deep Link — външна връзка, отваряща конкретен екран на приложението. Navigation Component обработва deep links чрез атрибута app:deepLink в NavGraph. Системата създава PendingIntent, който възстановява навигационния стек до целевия екран, или създава нов стек, ако приложението не работи.

xml

<fragment android:id="@+id/profileFragment"
    android:name=".ProfileFragment">
    <deepLink
        app:uri="https://example.com/profile/{userId}" />
    <argument
        android:name="userId"
        app:argType="string" />
</fragment>

// Програмно създаване на Deep Link
val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.profileFragment)
    .setArguments(Bundle().apply {
        putString("userId", "user_123")
    })
    .createPendingIntent()

Deep Links поддържат URI шаблони с пътища и query параметри, intent action и mime type. Placeholder ({userId}) автоматично се свързва с аргумента destination. Navigation Component също обработва имплицитни deep links чрез AndroidManifest — достатъчно е да добавите intent-filter към Activity с NavHostFragment.

Navigation Compose (androidx.navigation:navigation-compose) — разширение на Navigation Component за Jetpack Compose. API запазва концепцията на NavController и NavHost, но екраните са Composable функции вместо Fragment. NavHost приема composable ламбда за всеки маршрут.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    startDestination = "home"
                ) {
                    composable("home") {
                        HomeScreen(
                            onItemClick = { id ->
                                navController.navigate("detail/$id")
                            }
                        )
                    }
                    composable(
                        route = "detail/{itemId}",
                        arguments = listOf(
                            navArgument("itemId") {
                                type = NavType.LongType
                            }
                        )
                    ) { backStackEntry ->
                        val itemId = backStackEntry
                            .arguments?.getLong("itemId") ?: 0L
                        DetailScreen(itemId = itemId)
                    }
                }
            }
        }
    }
}

Navigation Compose използва низови маршрути вместо id. Параметрите се предават чрез шаблон на маршрут ("detail/{itemId}") и се извличат от backStackEntry. rememberNavController() запазва NavController при рекомпозиция. За Type Safety в Compose се препоръчва модулът navigation-compose-type-safety (експериментален).

Често задавани въпроси

Какво е NavHost в Navigation Component?

NavHost — контейнер за показване на навигационни екрани. Реализира се чрез NavHostFragment в XML layout. NavHost проследява текущия екран в NavGraph и управлява преходите. Всяко Activity съдържа един NavHostFragment.

С какво Safe Args е по-добър от Bundle?

Safe Args — Gradle плъгин, генериращ типобезопасни класове аргументи. Bundle изисква ръчно посочване на ключове и типове, което води до грешки по време на изпълнение. Safe Args проверява типовете на етап компилация и автоматично сериализира данните.

Как се предават сложни обекти чрез Navigation Component?

Сложните обекти се предават чрез ViewModel (споделен между екрани) или чрез база данни с предаване на ID. Safe Args поддържа само примитиви, низове и Parcelable. Google препоръчва да избягвате предаването на големи обекти чрез навигационни аргументи.

Как работи Deep Link в Navigation Component?

Deep Link се конфигурира в NavGraph чрез атрибута app:deepLink. Navigation Component автоматично обработва входящите връзки, създава PendingIntent чрез NavDeepLinkBuilder и възстановява навигационния стек до целевия екран. Поддържа URI, intent action и mime type.

Може ли Navigation Component да се използва с Jetpack Compose?

Да. Navigation Compose (androidx.navigation:navigation-compose) предоставя NavHost за Compose. API е аналогичен на XML версията, но екраните са Composable функции. NavController се използва еднакво и в двете версии. Google препоръчва Navigation Compose за нови проекти в Compose.

Резюме

  • Navigation Component — Android Jetpack библиотека за централизирана навигация с NavController, NavHost и NavGraph
  • NavGraph — XML граф, описващ всички екрани (destination) и връзки (action) между тях
  • NavHostFragment — контейнер в layout на Activity, поддържащ атрибута defaultNavHost за бутона „Назад"
  • Safe Args — Gradle плъгин за типобезопасно предаване на аргументи с проверка на типове на етап компилация
  • Deep Links поддържат URI, intent action и mime type с автоматично възстановяване на навигационния стек
  • Navigation Compose — разширение за Jetpack Compose с низови маршрути и composable екрани
  • Navigation Component е единственият препоръчан от Google начин за навигация в нови Android проекти

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също