← Назад к вопросам

Как открыть экран в Android приложении

1.0 Junior🔥 282 комментариев
#Android компоненты#Жизненный цикл и навигация

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Открытие экрана (Activity) в Android-приложении — фундаментальная операция. В современной разработке это можно сделать несколькими способами, зависящими от архитектуры и используемых библиотек. Рассмотрим основные подходы.

1. Классический способ: Intent и startActivity()

Базовый и исторически первый метод. Для открытия новой Activity создается объект Intent, который описывает намерение и цель.

Открытие стандартной Activity

// Внутри исходной Activity (например, MainActivity)
val intent = Intent(this, DetailActivity::class.java)
startActivity(intent)

Передача данных между экранами

Данные передаются через Extras (пары "ключ-значение").

// Отправка данных из MainActivity
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("USER_ID", 123)
intent.putExtra("USER_NAME", "Иван")
startActivity(intent)

// Получение данных в ProfileActivity
val userId = intent.getIntExtra("USER_ID", -1) // -1 - значение по умолчанию
val userName = intent.getStringExtra("USER_NAME")

Неявные интенты и взаимодействие с системой

Intent также позволяет запускать Activity других приложений или системные компоненты (галерею, звонки).

// Открытие веб-страницы в браузере
val webIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://developer.android.com"))
startActivity(webIntent)

2. Современный подход: Jetpack Navigation Component

С появлением архитектурных компонентов Jetpack предпочтительным способом навигации в приложениях с одной Activity и несколькими Fragments стал Navigation Component. Он упрощает управление переходами, передачу данных с type safety и интеграцию с ViewModel.

Основные элементы Navigation:

  • NavGraph (XML-файл) — граф навигации, описывающий все экраны (дестинации) и пути между ними.
  • NavController — центральный объект, управляющий навигацией по графу.
  • NavHostFragment — контейнер в макете Activity, где происходит отображение Fragments.

Пример навигации с Navigation Component

  1. Объявление графа (nav_graph.xml):
<?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"
    android:id="@+id/nav_graph"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.MainFragment"
        android:label="Main">
        <action
            android:id="@+id/action_main_to_detail"
            app:destination="@id/detailFragment" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name="com.example.DetailFragment"
        android:label="Detail">
        <argument
            android:name="itemId"
            app:argType="integer" />
    </fragment>
</navigation>
  1. Выполнение перехода во Fragment:
// В MainFragment. Используем безопасные аргументы (Safe Args).
val action = MainFragmentDirections.actionMainToDetail(itemId = 42)
findNavController().navigate(action)

Преимущества Navigation Component:

  • Визуальное представление графа навигации в Android Studio.
  • Безопасная передача аргументов (Safe Args) через сгенерированные классы, устраняющая ошибки типов.
  • Автоматическая обработка кнопки "Назад" и Up-навигации.
  • Глубокая linking.

3. Навигация в архитектуре MVVM / MVI с использованием SingleLiveEvent или StateFlow

В чистых архитектурных подходах View (Activity/Fragment) не должна напрямую управлять навигацией. Это прерогатива ViewModel. Команды навигации передаются как события.

Пример с StateFlow и Sealed Class:

// ViewModel
class MainViewModel : ViewModel() {
    private val _navigationEvent = MutableSharedFlow<NavigationCommand>()
    val navigationEvent = _navigationEvent.asSharedFlow()

    fun onItemSelected(itemId: Int) {
        viewModelScope.launch {
            _navigationEvent.emit(NavigationCommand.ToDetail(itemId))
        }
    }
}

sealed class NavigationCommand {
    data class ToDetail(val id: Int) : NavigationCommand()
    object Back : NavigationCommand()
    data class ToExternal(val url: String) : NavigationCommand()
}

// Activity или Fragment
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.navigationEvent.collect { command ->
            when (command) {
                is NavigationCommand.ToDetail -> {
                    val direction = MainFragmentDirections.actionMainToDetail(command.id)
                    findNavController().navigate(direction)
                }
                is NavigationCommand.ToExternal -> {
                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(command.url))
                    startActivity(intent)
                }
                NavigationCommand.Back -> findNavController().navigateUp()
            }
        }
    }
}

Ключевые рекомендации по выбору метода:

  • Для простых приложений или одноразовых переходов достаточно классического Intent.
  • Для современных приложений со сложной навигацией между Fragments используйте Jetpack Navigation Component.
  • Для проектов с четкой архитектурой (Clean Architecture, MVVM) комбинируйте Navigation Component с паттерном событий из ViewModel (StateFlow, SharedFlow).
  • Всегда учитывайте жизненный цикл компонентов, чтобы избежать утечек памяти и попыток навигации из неактивного состояния.

Выбор метода зависит от контекста, но тренд однозначно смещается в сторону использования Jetpack Navigation Component как стандарта для управления навигацией внутри приложения.

Как открыть экран в Android приложении | PrepBro