0

I have a fragment that starts a second activity upon some button click. This second activity is where the user makes some selections. I want to update a TextView in the fragment based on the user's selections from the second activity. I am using a ViewModelFactory in order to get access to the same ViewModel in the Fragment from within the second Activity (from the solution from Amir Raza found at: Android LiveData - how to reuse the same ViewModel on different activities?)

But the TextView is not being updated.

I found answers here:

Update textView in Fragment from Activity

But this answer does not use LiveData.

Fragment:

class CreatePlanFragment : Fragment()
    {
        private lateinit var vmCreatePlan: NameViewModel
        ...
        vmCreatePlan = ViewModelProviders.of(this, ViewModelFactory.getInstance()).get(NameViewModel::class.java)
        val tvStartReference: TextView = view.findViewById(R.id.create_plan_start_ref)
        vmCreatePlan.referenceStart.observe(this, Observer {
            tvStartReference.text = it
        })
    }   

Second Activity:

class ActivitySelectReference : AppCompatActivity()
{
    private lateinit var vmCreatePlan: NameViewModel
    ...
    vmCreatePlan = ViewModelProviders.of(this, ViewModelFactory.getInstance()).get(NameViewModel::class.java)

    reference_button_ok.setOnClickListener {
            vmCreatePlan.referenceStart.postValue("New Label")
            //vmCreatePlan.referenceStart.value ="New Label"
            finish()
        }

}

ViewModel:

class NameViewModel : ViewModel()
{
    val referenceStart: MutableLiveData<String> = MutableLiveData<String>().apply {
        value = "Old Label"
    }

    companion object
    {
        private var instance: NameViewModel? = null
        fun getInstance() = instance ?: synchronized(NameViewModel::class.java) {
            instance ?: NameViewModel().also { instance = it }
        }
    }
}

ViewModelFactory:

class ViewModelFactory : ViewModelProvider.NewInstanceFactory()
{
    override fun <T : ViewModel?> create(modelClass: Class<T>) = with(modelClass) {
        when
        {
            isAssignableFrom(NameViewModel::class.java) -> NameViewModel.getInstance()
            else -> throw IllegalArgumentException("Unknown viewModel class $modelClass")
        }
    } as T

    companion object
    {
        private var instance: ViewModelFactory? = null
        fun getInstance() = instance ?: synchronized(ViewModelFactory::class.java) {
            instance ?: ViewModelFactory().also { instance = it }
        }
    }
}
Samuel
  • 395
  • 2
  • 5
  • 20
  • Can you try using `activity` property instead of `this` in your fragment? Let me know what happens please – Nizar Jan 23 '20 at 21:17
  • This does not do anything: activity?.let{vmCreatePlan = ViewModelProviders.of(it,ViewModelFactory.getInstance()).get(NameViewModel::class.java)}. ViewModelProviders take FragmentActivity: https://developer.android.com/reference/android/arch/lifecycle/ViewModelProviders – Samuel Jan 23 '20 at 22:19
  • It seems all good but strange why your livedata is not updating. You can debug it to catch the culprit. Can you please share a bit detail of your `Fragment` and `Second Activity`? – Amir Raza Jan 25 '20 at 16:28
  • I made a rookie mistake. It does work now. Thanks! – Samuel Jan 27 '20 at 17:30

0 Answers0