Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observe LiveData instance in fragment and activity

Tags:

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?

like image 645
Nelson Almendra Avatar asked Mar 13 '19 10:03

Nelson Almendra


2 Answers

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

like image 57
Sam Rendal Avatar answered Oct 19 '22 17:10

Sam Rendal


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
    })
like image 38
Abd Nezar Avatar answered Oct 19 '22 16:10

Abd Nezar