У меня есть фрагмент с функцией updateToolbar()
. Когда я пытаюсь получить свою ViewModel, вызывает UserViewModel по этому методу, я получаю ошибку:
Can't create ViewModelProvider for detached fragment
Когда я пытаюсь получить UserViewModel внутри onViewCreated()
, все работает нормально. Почему так происходит? Я вызываю updateToolbar()
после onCreateView()
, и я не создаю никаких транзакций фрагмента до вызова функции.
Я начал изучать Чистую Архитектуру, и я думаю, что причина ошибки может заключаться в этом, поэтому я тоже добавляю этот код. Я думаю, что проблема с докладчиком, но я не могу понять, где именно.
PacksFragment:
class PacksFragment : BaseCompatFragment() {
@Inject
lateinit var presenter: PacksFragmentPresenter
private var userViewModel: UserViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) {
userViewModel = ViewModelProviders.of(this).get(UserViewModel::class.java)
super.onCreate(savedInstanceState)
}
override fun onCreateView(
...
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
LibApp.get().injector.inject(this)
...
presenter.openNewPack(packId)
}
fun updateToolbar() {
Timber.e((userViewModel == null).toString())
Timber.e(userViewModel?.getData()?.value?.coins.toString())
}
}
PacksFragmentPresenter:
class PacksFragmentPresenter @Inject constructor(
private val packsFragment: PacksFragment,
private val getCoinsFromUserCase: GetCoinsFromUserCase
) {
fun openNewPack(packId: Int) {
if (getCoinsFromUserCase.getCoinsFromUser()){
packsFragment.updateToolbar()
}
}
}
GetCoinsFromUserCase:
class GetCoinsFromUserCase {
fun getCoinsFromUser(): Boolean {
val userViewModel = UserViewModel()
userViewModel.takeCoins(10)
return true
}
}
userViewModel:
class UserViewModel : ViewModel(), UserApi {
private val data = MutableLiveData<User>()
fun setData(user: User) {
//Logged fine
Timber.e("User setted")
data.value = user
}
fun getData(): LiveData<User> {
if (data.value == null) {
val user = User()
user.coins = 200
data.value = user
}
//Logged fine, "false"
Timber.e("User getted")
Timber.e("Is user == null? %s", (data.value == null).toString())
return data
}
override fun takeCoins(value: Int) {
//Specially commented it
// getCoins(value)
}
}
UPD:
Я делаю некоторые изменения, чтобы предотвратить раздавление - сделайте userViewModel обнуляемым (обновите PacksFragment код сверху).
Но userViewModel всегда нулевой, когда я звоню updateToolbar()
. Основной фрагмент не удален / удален / невидим / ..., это активный фрагмент с кнопкой, вызвавшей функцию updateToolbar()
.