AlertDialog повторно отображается при изменении ориентации - PullRequest
0 голосов
/ 11 октября 2018

Код вопроса на Github
У меня есть приложение, которое использует фрагменты + viewmodels.В одном фрагменте мне нужно представить список опций пользователю, когда они нажимают кнопку.Я делаю это с помощью AlertDialog Builder, и это работает, чтобы решить эту проблему.Но если я открою приложение, нажмите кнопку, чтобы отобразить alerttdialog, закройте диалоговое окно, а затем поверните телефон, чтобы вызвать демонтаж / сборку повторного вызова alerttdialog.

Я использую привязку данных Android для привязки пользовательского интерфейса.вещи для ViewModel (не уверен, если это имеет значение).Таким образом, основной поток таков:

  • Запускается приложение
  • Фрагмент подписывается на 1, наблюдаемую в ViewModel
  • Кнопка пользовательских нажатий
  • Из-за привязки данныхщелчок обрабатывается во ViewModel с помощью метода buttonClicked ()
  • Внутри функции vm.buttonClicked () Я получаю данные и обновляю наблюдаемое, которое наблюдает фрагмент
  • Фрагмент см. новые данные в наблюдаемой
  • Фрагмент создает AlertDialog в коде и показывает диалоговое окно для пользователя
  • Пользователь либо делает выбор, либо закрывает диалоговое окно
  • Пользователь поворачивает телефон, вызывает изменение жизненного цикла
  • КогдаUI Get восстановлен, он снова показывает AlertDialog

Я создал простую демонстрацию на github .

Если вы клонируете этот репозиторий, а затем запустите приложение, но НЕ нажимайте кнопку, изменения ориентации идут, как и ожидалось.Если нажать кнопку и закрыть диалоговое окно, а затем повернуть телефон, вы увидите, что AlertDialog get повторно отображается.

1 Ответ

0 голосов
/ 11 октября 2018

Жизненный цикл ViewModel отличается от жизненного цикла фрагмента.Когда ориентация изменяется, Фрагмент воссоздается, но ViewModel остается.

Теперь, что происходит, когда вы обновляете значение MutableLiveData, оно передает обновление Наблюдателю;когда Фрагмент воссоздается при смене чередования, он снова подписывается на LiveData, и, поскольку происходит обновление значения, MutableLiveData передает это обновление недавно подписанному наблюдателю.

Так что вам следует, например,сохраните состояние фрагмента в onSaveInstanceState, используйте saveInstanceState, чтобы получить последнее обновление значения MutableLiveData и проверьте, произошло ли изменение в наблюдателе, прежде чем показывать диалоговое окно.

Или вы можете переместить логику диалогана обработчик клика.По моему мнению, показ диалога в Обозревателе не очень хороший подход.

...