AlertDialog在方向更改时重新显示

时间:2018-10-10 22:04:36

标签: android android-fragments android-lifecycle android-databinding android-architecture-components

Code for question on Github
我有一个使用片段+视图模型的应用程序。在一个片段中,当用户按下按钮时,我需要向他们提供选项列表。我正在使用AlertDialog构建器执行此操作,它可以解决该问题。但是,如果我打开该应用程序,请点击按钮以显示警报对话框,关闭对话框,然后旋转手机以触发拆解/重新构建警报对话框。

我正在使用Android的数据绑定将ui内容绑定到ViewModel(不确定是否重要)。所以基本流程是:

  • 应用启动
  • Fragment订阅了ViewModel中可观察到的1个
  • 用户点击按钮
  • 由于进行数据绑定,因此单击是在按钮模型中由buttonClicked()方法处理的
  • 在vm.buttonClicked()函数内部,我获取数据并更新片段正在观察的可观察对象
  • 可以看到的碎片见的新数据
  • Fragment在代码中创建AlertDialog并向用户显示对话框
  • 用户进行选择或关闭对话框
  • 用户旋转手机,导致生命周期更改
  • 重建用户界面时,它再次显示AlertDialog

我在github上创建了一个简单的演示。

如果您克隆该仓库,然后启动应用程序,但不要按该按钮,则方向更改将按预期进行。如果单击该按钮并关闭对话框,然后旋转手机,您将看到重新显示AlertDialog。

2 个答案:

答案 0 :(得分:0)

ViewModel的生命周期不同于片段的生命周期。当方向更改时,将重新创建Fragment,但ViewModel保留。

现在发生的是,当您更新MutableLiveData的值时,它将向观察者广播更新;当根据轮换更改重新创建Fragment时,它将再次重新订阅LiveData,并且由于值存在更新,因此MutableLiveData会将更新广播给新订阅的观察者。

例如,您应该将片段状态保存在onSaveInstanceState中,使用savedInstanceState获取对MutableLiveData值的最后更新,并在显示对话框之前检查观察者是否发生了更改。

或者您可以将对话框逻辑移动到单击处理程序。我认为在观察员中显示对话框不是一个好方法。

答案 1 :(得分:0)

如果您正在使用LiveData和事件,this可以帮助您解决某些情况。总之,您应该使用 SingleLiveEvents