Как можно организовать взаимодействие Activity и фрагмента?

Взаимодействие между Activity и Fragment в Android может быть организовано разными способами, в зависимости от направления передачи данных (от Activity к Fragment, от Fragment к Activity, между несколькими Fragment) и сложности архитектуры (MVVM, MVP и т.д.).

Ниже представлены основные и рекомендуемые способы связи между Activity и Fragment.

🔁 1. Передача данных от Activity к Fragment

🧩 Через arguments

При создании фрагмента можно передать аргументы с помощью Bundle:

val fragment = MyFragment().apply {
arguments = Bundle().apply {
putString("key", "value")
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit()

Внутри фрагмента:

val value = arguments?.getString("key")

🔹 Этот способ подходит для инициализации данных (например, ID объекта, имя пользователя и т.д.).

🧬 Через вызов метода фрагмента

Если фрагмент уже добавлен и получен по tag или id:

val fragment = supportFragmentManager.findFragmentByTag("MyFragment") as? MyFragment
fragment?.updateData("новые данные")

Во фрагменте:

fun updateData(data: String) {
// обработка
}

🔄 2. Передача данных от Fragment к Activity

🗣 Через интерфейс (классический способ)

Фрагмент объявляет интерфейс:

interface OnDataPass {
fun onDataPass(data: String)
}

В фрагменте:

private var callback: OnDataPass? = null
override fun onAttach(context: Context) {
super.onAttach(context)
callback = context as? OnDataPass
}
fun sendData() {
callback?.onDataPass("Привет из фрагмента")
}

В Activity:

class MainActivity : AppCompatActivity(), OnDataPass {
override fun onDataPass(data: String) {
// обработка данных
}
}

🧠 Через ViewModel (рекомендуемый способ в MVVM)

Создаётся общая ViewModel, привязанная к activity, чтобы использовать LiveData/StateFlow.

class SharedViewModel : ViewModel() {
val message = MutableLiveData<String>()
}

В Activity и Fragment:

val viewModel: SharedViewModel by activityViewModels()

Передача:

viewModel.message.value = "Данные от фрагмента"

Прослушивание:

viewModel.message.observe(viewLifecycleOwner) {
// обработка
}

🔹 Этот способ особенно удобен при взаимодействии нескольких фрагментов через одну Activity.

🔃 3. Взаимодействие между фрагментами через Activity

Часто реализуется так:

  • Один фрагмент передаёт данные в ViewModel или через интерфейс в Activity.

  • Activity передаёт их другому фрагменту через:

    • arguments,

    • вызов метода,

    • ту же SharedViewModel.

📎 Дополнительные подходы

📦 Использование FragmentResult API (современный способ)

Фрагмент-отправитель:

val result = Bundle().apply {
putString("key", "value")
}
setFragmentResult("requestKey", result)

Фрагмент-получатель:

setFragmentResultListener("requestKey") { key, bundle ->
val data = bundle.getString("key")
}

🔹 Удобно, когда нужно передать результат от дочернего к родительскому фрагменту или между ними без Activity.

✅ Выбор подхода

Задача Подход
Инициализация фрагмента arguments
--- ---
Вызов метода фрагмента Получение по id/tag + публичный метод
--- ---
Простая передача от фрагмента к Activity Интерфейс или FragmentResult API
--- ---
Реактивное и безопасное взаимодействие SharedViewModel с LiveData или StateFlow
--- ---
Передача результата от одного фрагмента другому FragmentResult API
--- ---

Таким образом, Android предлагает гибкие и безопасные способы связи между Activity и Fragment. В современном коде предпочтение отдаётся ViewModel и FragmentResult API, так как они лучше отделяют логику от представления и упрощают поддержку кода.