Встречается на 40% собеседований по Mobile

Для чего нужны фрагменты, если есть Activity

Фрагменты — это модульные части пользовательского интерфейса внутри Activity, которые имеют собственный жизненный цикл, получают собственные входящие события и могут добавляться или удаляться во время выполнения активности. Они нужны для создания модульных, переиспользуемых и адаптивных интерфейсов, которые сложно или невозможно реализовать с помощью одной Activity.

Зачем нужны фрагменты, если есть Activity

Activity — это экран приложения, но она не всегда удобна для организации сложного интерфейса. Фрагменты решают несколько ключевых задач:

  • Модульность: разбивают интерфейс на независимые части, которые проще разрабатывать и тестировать.
  • Переиспользование: один и тот же фрагмент можно встраивать в разные Activity, избегая дублирования кода.
  • Адаптивность: позволяют по-разному компоновать интерфейс на планшетах и телефонах, например, показывать два фрагмента рядом на широком экране и по одному — на узком.
  • Динамичность: фрагменты можно добавлять, удалять или заменять в рантайме, что удобно для экранов с изменяемым содержимым.
  • Управление жизненным циклом: у фрагмента есть свой жизненный цикл, привязанный к жизненному циклу Activity, что упрощает управление ресурсами.

Как это работает

Фрагмент — это класс, наследующий от Fragment. Он имеет собственные методы жизненного цикла: onCreate, onCreateView, onStart, onResume, onPause, onStop, onDestroyView, onDestroy. Эти методы вызываются в зависимости от состояния Activity-хозяина.

Фрагменты добавляются в Activity либо статически через XML-разметку, либо динамически через FragmentManager и FragmentTransaction. Пример динамического добавления:

kotlin
// Получаем FragmentManager
val fragmentManager = supportFragmentManager
// Начинаем транзакцию
val transaction = fragmentManager.beginTransaction()
// Добавляем фрагмент в контейнер с id container
val fragment = MyFragment()
transaction.replace(R.id.container, fragment)
// Добавляем транзакцию в back stack, чтобы можно было вернуться
transaction.addToBackStack(null)
// Применяем транзакцию
transaction.commit()

Пример: адаптивный интерфейс

Рассмотрим приложение для просмотра списка и деталей. На планшете удобно показывать список слева и детали справа, а на телефоне — только один экран за раз.

  • Создаём два фрагмента: ListFragment и DetailFragment.
  • В макете для планшета (layout-sw600dp) размещаем оба фрагмента в одном LinearLayout.
  • В макете для телефона (layout) размещаем только ListFragment.
  • При выборе элемента в списке на телефоне запускаем DetailActivity, а на планшете — заменяем DetailFragment в контейнере.

Этот подход позволяет переиспользовать фрагменты и избегать дублирования логики.

Подводные камни

  • Сложность жизненного цикла: фрагменты имеют собственный жизненный цикл, который может отличаться от жизненного цикла Activity. Нужно аккуратно работать с onSaveInstanceState и восстановлением состояния.
  • Передача данных: для обмена данными между фрагментами часто используют ViewModel или интерфейсы, чтобы не создавать жёсткие связи.
  • Back stack: при использовании addToBackStack нужно помнить, что фрагменты не уничтожаются сразу, а сохраняются в стеке, что может привести к утечкам памяти, если не очищать ссылки.
  • Избыточность: для простых экранов фрагменты могут быть излишни; иногда достаточно одной Activity с несколькими View.

Когда использовать фрагменты

Фрагменты оправданы, когда:

  • Нужен адаптивный интерфейс для разных размеров экранов.
  • Один и тот же компонент используется в нескольких местах приложения.
  • Интерфейс динамически меняется (например, мастер-детали, вкладки, слайдеры).
  • Требуется разделить сложный экран на независимые модули для упрощения тестирования.

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

Коротко

  • Фрагменты — модульные части UI внутри Activity, со своим жизненным циклом.
  • Они дают модульность, переиспользование, адаптивность и динамичность интерфейса.
  • Фрагменты добавляются через FragmentManager и FragmentTransaction.
  • Используйте фрагменты для сложных, адаптивных или переиспользуемых интерфейсов; для простых экранов достаточно Activity.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы