Android Arch组件ViewModel和LiveData在屏幕旋转后触发

Android Arch组件ViewModel和LiveData在屏幕旋转后触发,android,android-architecture-components,android-livedata,android-viewmodel,Android,Android Architecture Components,Android Livedata,Android Viewmodel,我在使用ViewModel和LiveData时遇到问题我是新使用ViewModel和LiveData arch组件的人,在使用片段和旋转屏幕时遇到问题观察员被触发。。。 我试着搬动那辆车 viewModel=ViewModelProviders.of(this.get)(MainViewModel::class.java) 在所有片段生命周期方法中,但没有成功 我的场景非常简单: 带有电子邮件和密码的登录屏幕 用户单击“登录”按钮 viewmodel调用登录(电子邮件、密码)并设置LiveDat

我在使用
ViewModel
LiveData
时遇到问题我是新使用ViewModel和LiveData arch组件的人,在使用
片段
和旋转屏幕时遇到问题观察员被触发。。。 我试着搬动那辆车

viewModel=ViewModelProviders.of(this.get)(MainViewModel::class.java)
在所有片段生命周期方法中,但没有成功

我的场景非常简单:

  • 带有电子邮件和密码的登录屏幕
  • 用户单击“登录”按钮
  • viewmodel调用
    登录(电子邮件、密码)
    并设置LiveData对象的值
  • 就现在来说,请大家举杯
  • 在这一点上,一切都是好的。但当我旋转屏幕时,土司再次出现,没有任何用户交互

    我必须在onDestroyView()中执行某些操作吗


    提前谢谢

    这就是LiveData和ViewModel的工作方式。当您调用
    ViewModelProviders.of(this.get)(MainViewModel::class.java)
    时,您将使用相同的LiveData获得相同的ViewModel,并且LiveData具有以前的对象,例如User,以及以前的凭据。您可以重置LiveData的用户
    onPause()
    onStop()
    以将其重置为初始状态


    我不知道你怎么称呼toast,如果你能分享你的ViewModel和MainActivity,我可以说得更具体。

    好的,终于找到了问题和解决方法。LiveData不是为单个事件设计的。出于这个原因,有几种方法可以修复或处理它,这两个链接对我很有用:

    基本上:

    在ViewModel中:

    var eventLiveData:MutableLiveData=MutableLiveData()

    在活动或片段中:

    viewModel.eventLiveData.observe(this, EventObserver {
         it?.let {
              shortToast(it.message)
         }
    })
    

    我使用ViewModel作为演示者。执行所有的业务逻辑,比如调用登录端点、保存缓存以及将json数据传递给livedata.value以触发观察者。这就是您应该如何使用ViewModel,没关系。有些示例还使用它,比如presenter发送弱视图引用作为调用活动方法的接口,或者使用LiveData状态调用方法。我想说的是,ViewModel的好处在于,在旋转之后,可以得到相同的ViewModel,它具有以前的状态和数据。在你的例子中,LiveData。您应该重置用户并在MutableLiveData上调用setValue(livedata.getUser())。然后在旋转前执行onPause()或onStop(),好的,就像其他需要清除或取消订阅销毁方法的组件一样?我以为它会自动处理。直到ViewModel被销毁,它才会被清除。您应该查看ViewModel生命周期。ViewModel的优点是能够在旋转后或在不同片段内使用它进行片段间通信。您在某个片段中设置LiveData的值,并在另一个片段上观察它,它将保留其值和状态,直到调用onDestroy()和ViewModel的onCleared()方法为止。也许会有帮助。谢谢!第一个链接是阅读本文的第一件事。例如,基于thr第一个链接,让';假设加载所有用户后,您会显示一个祝酒词,上面写着“用户同步完成”。如果旋转屏幕,土司将再次出现。我在google文档中看到,他们验证livedata对象是否为null。我正在使用kotlin在构造函数中初始化一个inmutable对象。我应该使用一些延迟初始化吗?你能发布更多的信息吗?我想知道当你点击按钮时你是如何调用login方法的,以及该方法在ViewModel中的内部作用。当然!今天就可以了。谢谢@色雷斯人,看看这个!我使用LiveData作为我的xml>ViewModel>Fragment中的点击监听器。如果我在监听单击后将该值设置为null,则在屏幕上观察到LiveData为null。您必须检查片段中的数据是否为null。这是一个黑客,但工作
    fun contentClicked(content:content){contentSelected.value=content;contentSelected.value=null;}