Ответ
Состояние View может не сохраняться во фрагменте по нескольким причинам:
- Отсутствие ID у View – для сохранения состояния у View должен быть установлен
android:id. Без ID система не знает, как сопоставить состояние.
<TextView
android:id="@+id/myTextView" <!-- без этого состояние не сохранится -->
... />
-
Фрагмент не вызывал
onSaveInstanceState()– если фрагмент был уничтожен (например, при повороте экрана), но не сохранил состояние. -
saveEnabled = false– явное отключение сохранения состояния у View:
myView.isSaveEnabled = false
-
Использование
setRetainInstance(true)– это сохраняет экземпляр фрагмента, но не состояние его View. -
Неправильная работа с
Bundle– если вonSaveInstanceState()не сохраняются нужные данные или не восстанавливаются вonViewStateRestored().
Ответ 18+ 🔞
Эй, слушай, тут такая тема с фрагментами, просто ёперный театр. Бывает, накрутишь логику, а потом бац — повернул экран, и все твои текстовые поля, свитчи и прогресс-бары обнулились, будто их и не было. Сам от себя охуеешь. А причина-то простая, как три копейки.
Первое и главное — это ID у вьюхи. Если ты в разметке не прописал android:id, то система просто нихуя не поймёт, чьё состояние куда складывать и откуда потом доставать. Это как прийти на склад и сказать: «Верните мою коробку». А тебе в ответ: «А какая твоя?». Все коробки одинаковые, блядь. Так и тут. Без ID — нет уникальности, нет сохранения.
<Switch
android:id="@+id/mySwitch" <!-- Вот эта хуйня обязательна! Без неё состояние накроется медным тазом -->
... />
Второй момент — сам фрагмент мог не вызвать onSaveInstanceState(). Это если его совсем убили, а не просто засунули в бэкстек. Но обычно система это делает за тебя, если только ты не накосячил с жизненным циклом.
Третья причина — ты мог сам, своими кривыми руками, отключить сохранение состояния для конкретной вьюхи. Сказал ей: «Не надо, я сам!», а потом забыл. И она тебе: «Окей, начальник, как скажешь» — и не сохраняет ни хуя.
myCustomView.isSaveEnabled = false // Вот после этой строчки можешь попрощаться с состоянием этой вьюхи
Четвёртый подводный камень — setRetainInstance(true). О, это хитрая жопа! Многие думают: «Вот, поставлю true, и фрагмент будет жить вечно со всеми данными». Ан нет, чувак. Этот флаг сохраняет сам объект фрагмента в памяти (чтобы не пересоздавался), но состояние его вьюх — нет! Вьюхи-то всё равно уничтожаются и создаются заново. Так что не ведись на эту уловку.
И наконец, классика жанра — косяки с Bundle. Ты в onSaveInstanceState() мог забыть что-то положить в сумку, или положить не туда, или в onViewStateRestored() не достать. А может, достал, но не присвоил обратно вьюхам. В итоге bundle есть, данные есть, а на экране — пусто. Удивление пиздец.
Короче, алгоритм простой: всегда ставь ID, не выключай сохранение без причины, помни про ограничения retainInstance и аккуратно работай с бандлом. Тогда и волнение ебать будет минимальным.