Почему нельзя передать данные через конструктор в Fragment

Ответ

Фрагменты пересоздаются системой (например, при повороте экрана), и Android автоматически вызывает конструктор без параметров. Если передавать данные через конструктор, они будут потеряны при пересоздании.

Вместо этого используйте Bundle через arguments:

// Создание фрагмента с аргументами
val fragment = MyFragment().apply {
    arguments = bundleOf("key" to value)
}

// Чтение в фрагменте
val value = arguments?.getString("key")

Так данные сохраняются при пересоздании. Альтернативно можно использовать ViewModel или Dagger для инъекции зависимостей.

Ответ 18+ 🔞

А, ну это классика, ёпта! Смотри, тут история про фрагменты в андроиде, которая у каждого новичка мозг выносит. Представь: ты такой красавчик, пишешь свой фрагмент, передаёшь в конструктор какие-то важные данные — MyFragment(importantData). И вроде всё летает, ты уже мысленно прикидываешь, на что первую премию потратишь.

А потом — бац! — пользователь экран повернул, или приложение в фон ушло и систему память почистила. И твой фрагмент, сука, пересоздаётся. И знаешь, что делает Android в этот момент? Он вызывает конструктор без параметров! Твой красивый MyFragment(importantData) идёт лесом, все эти данные накрываются медным тазом. Просто взяли и выкинули, как будто их и не было. Волнение ебать, правда?

Вот поэтому все эти умные дядьки из Гугла и придумали штуку под названием Bundle и arguments. Суть в чём? Вместо того чтобы пихать данные в конструктор, ты их засовываешь в специальную сумку (Bundle) и пристёгиваешь к фрагменту, прежде чем его показать.

Делается это как-то так, смотри:

// Создаём фрагмент и сразу пихаем в него данные
val fragment = MyFragment().apply {
    arguments = bundleOf("key" to value) // bundleOf — это удобная функция из androidx
}

А внутри самого фрагмента, когда тебе эти данные понадобятся (например, в onCreateView), ты просто лезешь в эту сумку и достаёшь оттуда своё добро:

// Чтение в фрагменте
val value = arguments?.getString("key")

Вот и вся магия. Система, когда убивает и заново рождает твой фрагмент, эту сумку (arguments) сохраняет и потом аккуратно пристёгивает обратно к новому экземпляру. Данные на месте, все живы-здоровы.

Ну а если тебе этот способ кажется немного староватым, типа "как будто на дворе 2012-й год", есть и другие варианты. Можно, например, использовать ViewModel — она переживает пересоздание фрагмента и данные в ней сохраняются. Или, если ты совсем мажор, заюзать какую-нибудь библиотеку для инъекции зависимостей вроде Dagger или Hilt, они тоже с этой проблемой помогают.

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