16

I have a simple scenario where I do something in fragment and when I receive the LiveData I want to do something in Activity.

ViewModel:

class MyViewModel(application: Application) : AndroidViewModel(application) {
    
   ...
    
    fun getUser(id: String): LiveData<User> {
        return repository.getUser(id)
    }
}

Fragment:

class MyFragment : Fragment() {

    private lateinit var myViewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activity?.run {
            myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
        } ?: throw Exception("Invalid Activity")
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        button.setOnClickListener {
            showProgressBar()
            myViewModel.getUser(editText.text.toString()).observe(this, Observer { it ->
                //TODO
            })
        }
    }
}

Activity:

class MainActivity : AppCompatActivity() {

    private lateinit var myViewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        myViewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
        //Here I would like to observe the user instance returned from the getUser() method
    }
}

So the issue I'm having is that I would like to have an instance of LiveData<User> in MyViewModel so that I could observe it in Activity and Fragment. How can I achieve this?

3
  • 2
    You can share the ViewModel between the activity and fragment....pass parent activity instance to ViewModelProviders.of() in your fragment (or even better use sharedViewModel if using Koin!) Commented Mar 13, 2019 at 10:44
  • I think I'm doing that already, the this instance that I'm passing to ViewModelProviders.of() is the activity itself Commented Mar 13, 2019 at 10:53
  • Save user data from FragmentViewModel to database .Define another viewModel for your activity and subscribe your Activity to observe changes in this database . I think this will be much more cleaner to implement and understand @NelsonAlmendra Commented Mar 25, 2019 at 18:44

3 Answers 3

15

In Fragemnts (as best practice) Should Use

viewModel.userLiveData.observe(viewLifecycleOwner, Observer {
    //your code here
})

In Activity Use

viewModel.userLiveData.observe(this, Observer {
        //your code here
    })
Sign up to request clarification or add additional context in comments.

Comments

4

in class MyViewModel create

    val userLiveData =MutableLiveData<User>()

and getter

    fun getUserLiveData(id: String): MutableLiveData<User> {
            return userLiveData
    }

    fun getUser(id: String){
    val disposableUser = repository.getUser(id)
    .subscribe({
        userLivedata.postValue(it)
    })

}

And in activity or Fragment called

   myViewModel.getUserLiveData.observe(this, Observer { it ->
      //TODO
    })
   myViewModel.getUser(...)

And Now in ViewModel you have object User (userLiveData.getValue())

Comments

1

Write method in Activity doSomethingWithUser(user: User)

And in your livedata

myViewModel.getUser(editText.text.toString()).observe(this, Observer { it ->
            (requireActivity() as MainActivity).doSomethingWithUser(it)
        })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.