У меня есть простой сценарий, в котором я что-то делаю во фрагменте, и когда я получаю LiveData, я хочу что-то сделать в Activity.
ViewModel:
class MyViewModel(application: Application) : AndroidViewModel(application) {
...
fun getUser(id: String): LiveData<User> {
return repository.getUser(id)
}
}
Фрагмент:
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
})
}
}
}
Деятельность:
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
}
}
Итак, проблема, с которой я столкнулся, заключается в том, что я хотел бы иметь экземпляр LiveData<User> в MyViewModel, чтобы я мог наблюдать за ним в Activity и Fragment. Как я могу этого добиться?
Я думаю, что уже делаю это, экземпляр this, к которому я перехожу ViewModelProviders.of(), — это сама активность
Сохраните пользовательские данные из FragmentViewModel в базу данных. Определите другую модель представления для своей деятельности и подпишитесь на свою активность, чтобы наблюдать за изменениями в этой базе данных. Я думаю, что это будет намного чище для реализации и понимания @NelsonAlmendra.
в классе MyViewModel создать
val userLiveData =MutableLiveData<User>()
и добытчик
fun getUserLiveData(id: String): MutableLiveData<User> {
return userLiveData
}
fun getUser(id: String){
val disposableUser = repository.getUser(id)
.subscribe({
userLivedata.postValue(it)
})
}
И в действии или фрагменте, называемом
myViewModel.getUserLiveData.observe(this, Observer { it ->
//TODO
})
myViewModel.getUser(...)
И теперь в ViewModel у вас есть объект User (userLiveData.getValue())
Напишите метод в Activity doSomethingWithUser(user: User)
И в ваших живых данных
myViewModel.getUser(editText.text.toString()).observe(this, Observer { it ->
(requireActivity() as MainActivity).doSomethingWithUser(it)
})
Во фрагментах (как лучшая практика) следует использовать
viewModel.userLiveData.observe(viewLifecycleOwner, Observer {
//your code here
})
Использование в действии
viewModel.userLiveData.observe(this, Observer {
//your code here
})
Вы можете разделить ViewModel между активностью и фрагментом.... передать экземпляр родительской активности в
ViewModelProviders.of()в вашем фрагменте (или даже лучше использоватьsharedViewModel, если используете Koin!)