Search code examples
androidkotlinviewmodelandroid-databinding

Populating data from MainActivity to ViewModel not observed in fragment


I'm trying to populate some live data from within the MainActivity into a ViewModel. However, the Fragment only appears to observe the initial data once ("NO DATA YET") which is set in the ViewModel itself.

I've tried updating the data by adding a update() function in the ViewModel as well as setting uzTelNotifViewModel.uzTelNotification.value = "NEW DATA".

Can someone provide me some advice?

MainActivity

 override fun onCreate(savedInstanceState: Bundle?) {
   ...
   uzTelNotifViewModel = ViewModelProvider(this)[UzTelNotifViewModel::class.java]
   binding.uzTelNotifViewModel = uzTelNotifViewModel
   ...
}

override fun onCreate(savedInstanceState: Bundle?) {
  ...
  uzTelNotifViewModel.update("NEW DATA HERE")
  ...
}

UzTelNotifFragment

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.lifecycleOwner = viewLifecycleOwner
    useMaterialSharedAxisXForwardAnimation = false

    viewModel = ViewModelProvider(this)[UzTelNotifViewModel::class.java]
    binding.viewModel = viewModel

    viewModel.uzTelNotification.observe(viewLifecycleOwner) {
        binding.uzTelNotifBar.text = it.toString()
    }

UzTelNotifViewModel

class UzTelNotifViewModel : ViewModel() {
    val uzTelNotification = MutableLiveData<String>('NO DATA YET')
    val uzTelNotifVisible = MutableLiveData<Boolean>(true)

    fun update(data: String) {
        uzTelNotification.value = data
    }
}

uz_tel_notif_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="org.linphone.activities.main.viewmodels.UzTelNotifViewModel" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/uztelnotif_fragment_size"
        android:background="?attr/accentColor"
        android:orientation="horizontal"
        android:visibility="@{viewModel.uzTelNotifVisible ? View.VISIBLE : View.GONE, default=gone}"
        >

        <TextView
            android:id="@+id/uzTelNotifBar"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:gravity="center_vertical"
            android:paddingLeft="15dp"
            android:text="@{viewModel.uzTelNotification, default='none'}"
            android:textColor="?attr/accentTextColor"
            android:textSize="15sp" />

    </RelativeLayout>

Solution

  • It seems that you're observing the uzTelNotification LiveData in both the MainActivity and the UzTelNotifFragment. However, it's important to note that each ViewModel instance is scoped to its respective lifecycle owner, which means that the ViewModel instance in the MainActivity is different from the ViewModel instance in the UzTelNotifFragment.

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        binding.lifecycleOwner = viewLifecycleOwner
    
        // Retrieve the shared ViewModel instance from the MainActivity
        val uzTelNotifViewModel = ViewModelProvider(requireActivity())[UzTelNotifViewModel::class.java]
        binding.viewModel = uzTelNotifViewModel
    
        uzTelNotifViewModel.uzTelNotification.observe(viewLifecycleOwner) {
            binding.uzTelNotifBar.text = it.toString()
        }
    }