Fragment 从不接收来自 Shared ViewModel 的 LiveData 更新

Fragment Never Receives LiveData updates from Shared ViewModel

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

我的问题很简单:在 LiveData 更新后,我的片段中从未达到观察回调。为了测试,我尝试观察 MainActivity 中的数据,但效果很好。此外,观察我在其他 ViewModel 中声明的片段中的 LiveData 变量也能正常工作。奇怪的是,只有这个 ViewModel 的 LiveData 似乎对我的片段造成了问题。

我正在声明 ViewModel 并通过 Koin 将其注入我的 Activity 和 Fragment。我做错了什么,永远不会在我的片段中获取此 ViewModel 数据的更新?

ViewModel

class RFIDTagViewModel: ViewModel() {

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

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

Activity

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() }
}

您需要使用相同的视图模型,也就是 sharedViewModel,您正在使用相同视图模型的两个不同实例。

修复它。

在 activity 和片段上:

private val rfidViewModel: RFIDTagViewModel by activityViewModels()

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

在您的片段中,我看到您正在使用 viewModels()viewModels()这里会附加到Fragment,而不是Activity。

如果您想在 Fragment 和 Activity 之间共享 ViewModel,则在 Fragment 中使用 activityViewModels()。现在,在 Fragment 中,您的 shareViewModel 将附加到包含您的 Fragment 的 Activity。

编辑如下:

PickingItemFragment.kt

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

更多信息:Communicating with fragments