当前位置: 首页 > 知识库问答 >
问题:

Fragment从不从共享ViewModel接收LiveData更新

顾乐池
2023-03-14

我的应用程序使用MVVM架构。我有一个活动及其子片段共享的ViewModel。ViewModel包含一个简单的字符串,我想从活动中更新它,并在片段中观察它。

我的问题很简单:LiveData更新后,我的片段中永远不会到达observe回调。为了进行测试,我尝试在MainActivity中观察数据,但效果很好。此外,在我在其他ViewModels中声明的片段中观察LiveData变量也可以很好地工作。奇怪的是,只有这个ViewModel的LiveData似乎给我的片段带来了问题。

我声明了ViewModel,并通过Koin将其注入到我的活动和片段中。我做了什么不正确的事情,从来没有在我的片段中更新过这个ViewModel的数据?

视图模型

class RFIDTagViewModel: ViewModel() {

    private val _rfidTagUUID = MutableLiveData<String>()
    val rfidTagUUID: LiveData<String> = _rfidTagUUID

    fun tagUUIDScanned(tagUUID: String) {
        _rfidTagUUID.postValue(tagUUID)
    }
}

活动

class MainActivity : AppCompatActivity(), Readers.RFIDReaderEventHandler,
    RFIDSledEventHandler.TagScanInterface {
    private val rfidViewModel: RFIDTagViewModel by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        rfidViewModel.rfidTagUUID.observe(this, {
            Timber.d("I'm ALWAYS reached")
        })
    }
    override fun onResume() {
rfidViewModel.tagUUIDScanned(uuid) //TODO: data passed in here, never makes it to Fragment observer, only observed by Activity successfully

}
 }

碎片

class PickingItemFragment : Fragment() {
    private val rfidViewModel: RFIDTagViewModel by viewModel()


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        rfidViewModel.rfidTagUUID.observe(viewLifecycleOwner, { tagUUID ->
            Timber.d("I'm NEVER reached")
        })
}}

Koin DI配置

val appModule = module {
    viewModel { RFIDTagViewModel() }
}

共有2个答案

黎同
2023-03-14

您需要使用相同的viewmodel,也就是sharedViewModel,就像使用同一viewmodel的两个不同实例一样。

来修复它。

关于活动和片段:

private val rfidViewModel: RFIDTagViewModel by activityViewModels()

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=pt-br

宫瀚
2023-03-14

在您的片段中,我看到您使用的是viewModels()<代码>视图模型()此处将附加到片段,而不是活动。

如果您想在片段和活动之间共享ViewModel,那么在片段中可以使用activityViewModels()。现在,在片段中,您的shareViewModel将附加到包含片段的活动。

编辑如下:

PickingItemFragment。kt

class PickingItemFragment : Fragment() {
    private val rfidViewModel: RFIDTagViewModel by activityViewModels()
}

更多信息:与片段通信

 类似资料:
  • 我有一个单独的类来处理数据提取(特别是Firebase),我通常从它返回LiveData对象并异步更新它们。现在我希望将返回的数据存储在ViewModel中,但问题是为了获得所述值,我需要观察从数据提取类返回的LiveData对象。observe方法需要一个LifecycleOwner对象作为第一个参数,但我的ViewModel中显然没有这个对象,而且我知道我不应该在ViewModel中保留对ac

  • 我在任何地方都找不到这个问题,所以它很可能是简单得愚蠢的东西。 我试图注册我的应用程序的MainActivity,以便通过共享菜单接收其他应用程序的纯文本,但我做的似乎没有让它工作。当我在网络浏览器中选择文本并点击“共享”图标时,我的应用程序不会被列为选项。 我还尝试了其他操作,如和,但没有任何效果。我的问题是我的应用程序在共享菜单中没有作为一个选项出现。

  • 活动可以按以下方式访问此列表: 我的问题是,我要这样做: > 在函数中,我异步获取数据,首先检查数据库(房间)中的数据

  • 我正在思考架构组件/MVVM。 假设我有一个存储库、一个ViewModel和一个片段。我使用类作为包装器来公开网络状态,就像体系结构组件指南中建议的那样。 我的存储库目前看起来是这样的(为简洁起见进行了简化): 然后在ViewModel中,我还声明了一个可变LiveData: 最后,片段: 正如您所看到的,由于LiveData变量将在过程中重置(存储库将创建一个新实例),因此不会触发观察者会出现问

  • 我正在尝试将数据从DialogFraank发送到创建此对话框的Fraank。在目标片段中,我使用以下代码: 我还在fragment实现了我的接口: 在DialogFragment中,我使用以下代码: 并发送数据: 我还试图从这个问题中使用onActivityResult(): 接收数据: 但我没有收到数据:(((

  • 首先请不要把这个问题当作重复的问题。所有其他问题都是旧的,我已经尝试了其中大多数的解决方案,但没有一个奏效。 我正在开发一个Android应用程序,我已经将我的应用程序添加到共享Android菜单中。我想添加功能,这样如果用户在共享列表上单击我的应用,例如在Chrome浏览器或Google Drive应用中,我的应用将从该应用接收数据,例如从Chrome it wold URL。 我尝试过使用不同