Наблюдайте за экземпляром LiveData во фрагменте и активности

У меня есть простой сценарий, в котором я что-то делаю во фрагменте, и когда я получаю 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. Как я могу этого добиться?

Вы можете разделить ViewModel между активностью и фрагментом.... передать экземпляр родительской активности в ViewModelProviders.of() в вашем фрагменте (или даже лучше использовать sharedViewModel, если используете Koin!)

John O'Reilly 13.03.2019 11:44

Я думаю, что уже делаю это, экземпляр this, к которому я перехожу ViewModelProviders.of(), — это сама активность

Nelson Almendra 13.03.2019 11:53

Сохраните пользовательские данные из FragmentViewModel в базу данных. Определите другую модель представления для своей деятельности и подпишитесь на свою активность, чтобы наблюдать за изменениями в этой базе данных. Я думаю, что это будет намного чище для реализации и понимания @NelsonAlmendra.

Ayush Bansal 25.03.2019 19:44
6
3
14 332
3

Ответы 3

в классе 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
    })

Другие вопросы по теме