У меня есть два фрагмента: F1 и F2
F1 содержит:
Когда пользователь нажимает «далее», отображается F2, а F1 добавляется к backstack. Поэтому, когда пользователь снова нажимает на F2, он возвращается к F1.
Когда пользователь возвращается к F1, я хочу сбросить значение в EditText. Поскольку я хочу повторно инициализировать значение только при воссоздании представления, я сбрасываю значение в onViewCreated, а не в onResume.
Проблема, с которой я сталкиваюсь, заключается в том, что EditText автоматически заполняется системой, когда пользователь нажимает назад, когда он пытается восстановить фрагмент в его предыдущем состоянии.
Значение автоматически повторно подставляется в onViewStateRestored из комплекта saveInstanceState.
Итак, мой вопрос: стоит ли переопределить метод onViewStateRestored для отправки нулевого пакета в super (см. Ниже), поскольку это решает мою проблему?
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(null);
}
Это очень простой пример, но мой проект более сложен, и я не хочу сбрасывать весь пользовательский интерфейс onResume, поскольку в этом нет необходимости, поскольку он не должен был быть изменен, поскольку он не уничтожен. Но я хочу, чтобы представление было сброшено, когда пользовательский интерфейс воссоздается с нуля (что происходит только тогда, когда фрагмент восстанавливается из backstack)
Согласно Жизненный цикл фрагмента ваше представление не уничтожается при открытии F2. Фрагмент просто остановлен. Итак, вы должны поместить свой код в onStart () или onResume ()
Это. Если вы посмотрите на Figure 2. The lifecycle of a fragment по своей ссылке, вы увидите, что onDestroyView вызывается при добавлении фрагмента в backstack, а onCreateView вызывается снова при восстановлении. Кстати, эта схема не завершена, так как не показывает вызов onViewStateRestored. Вот почему я обычно предпочитаю Вот этот, даже если не из официальной документации.
Интересная схема, спасибо за ссылку. По его мнению, вы правы (должен признать, это больно .. argh XD). Я все еще не понимаю, почему вы не можете поместить свой код в onStop ()? Мне кажется, что это правильное место, так как оно находится сразу после StateRestored (). Таким образом, ваше представление будет восстановлено, и вам просто нужно изменить те, которые вы хотите изменить.
Может ваша цель - пропустить StateRestored body? Если да, то вы должны перезаписать его, чтобы он оставался пустым. Но вы не должны инициализировать свое представление, поскольку оно предназначено только для восстановления сохраненного состояния в соответствии с док
Я хочу инициализировать пользовательский интерфейс в onViewCreated, то есть только тогда, когда представление правильно создано. Так что да, я хочу переопределить onViewStateRestored только для того, чтобы пропустить его. Я не хочу писать в этом методе больше, чем в примере выше
@vincrichaud Подожди, я ошибаюсь. В конце концов, похоже, это не сработало. Когда фрагмент восстанавливается из backstack, savedInstanceState уже равен нулю. Итак, когда будет восстановлено состояние EditText?
Может лучше использовать onResume как вы предложили
Думаю, он инициализирован в onViewCreated. В документе говорится, что вы должны переопределить его, чтобы инициализировать себя. Итак, я думаю, что внутри значения по умолчанию он вызывает частную функцию, которая восстанавливает сохраненное состояние.
@vincrichaud Да, но если вы переопределите onViewCreated и сначала вызовете его родительский код, ваш код все равно будет отменен системой позже. Самый безопасный способ - поместить свой код после вызова super в onViewStateRestored, как упоминается в документации: Called when all saved state has been restored into the view hierarchy of the fragment. Но поскольку этот метод вызывается только при восстановлении представления, лучше (как вы сказали) сделать это на onResume. Значит, ты тоже прав в конце ^^
So my question is: is it a good idea to override the onViewStateRestored method to send a null bundle to super (see below), as it solves my issue?
Скорее всего, нет. Подобные «небольшие» взломы обычно приводят к огромным WTF и длительным сеансам отладки в будущем.
Например, если я не ошибаюсь, этот хак сразу приведет к ошибке в контексте изменения конфигурации и потоков сохранения и восстановления. Поскольку в обоих этих потоках View фрагмента будет воссоздан, вы потеряете ввод пользователя.
Скорее всего, это не то поведение, которое вам нужно.
Я прочитал ваше обсуждение в комментариях и до сих пор не могу понять, почему вы настаиваете на том, чтобы очистка EditText была обусловлена воссозданием View фрагмента.
Вы хотите, чтобы этот EditText был пустым, если пользователь вернется к этому фрагменту, верно? Тогда, IMHO, лучшим решением будет очистить его при нажатии кнопки «Далее» перед переходом на F2.
Столкнулся с такими же проблемами.
Как я решил:
setSaveEnabled (ложь); для редактирования текста.
Создан класс модели Singlton
Как только я перейду к следующему фрагменту, сохраните данные в синглтонной модели.
Установите данные в CreateView из модели для редактирования текста.
Возможно, есть еще несколько оптимизированных решений, поэтому, пожалуйста, предлагайте их в комментариях.
Работаю на меня Спасибо !!
«Я сбрасываю значение в onViewCreated, а не в onResume». Зачем это нужно? Если вы хотите сбросить значение при отображении F1, вам следует сбросить EditText в onPause () или onResume ()