Егор Глухов
Егор Глухов

Reputation: 53

ViewModelProviders is outdated, what should be replaced?

I use ViewModelProviders. But today, after updating the library, there were 30 messages. As I understand ViewModelProviders was no longer available and you need to replace it, I looked in the developer.google but did not understand what to replace ? My code:

inline fun <reified T : ViewModel> FragmentActivity.injectViewModel(factory: ViewModelProvider.Factory): T {
    return ViewModelProviders.of(this, factory)[T::class.java]
}

inline fun <reified T : ViewModel> Fragment.injectViewModel(factory: ViewModelProvider.Factory): T {
    return ViewModelProviders.of(this, factory)[T::class.java]
}

and can you explain why it's out of date ?

Upvotes: 1

Views: 772

Answers (2)

Gv Ravi
Gv Ravi

Reputation: 391

you can use delegate if your ViewModel has some dependencies in this way...

protected val viewModel by activityViewModels<MainViewModel> {
    ViewModelFactory(ServicesRepo())
}

Upvotes: 0

ianhanniballake
ianhanniballake

Reputation: 199805

As per the documentation:

Use the by viewModels() Kotlin property delegate or ViewModelProvider.ViewModelProvider(ViewModelStoreOwner, Factory), passing in the fragment and factory.

So you can replace your extensions with:

inline fun <reified T : ViewModel> FragmentActivity.injectViewModel(factory:  ViewModelProvider.Factory): T {
    return ViewModelProvider(this, factory)[T::class.java]
}

inline fun <reified T : ViewModel> Fragment.injectViewModel(factory: ViewModelProvider.Factory): T {
    return ViewModelProvider(this, factory)[T::class.java]
}

And, as per the error message, you can instead use the Kotlin property extensions in the fragment-ktx and activity-ktx dependencies and remove your extension methods entirely.

Namely, by viewModels and by activityViewModels for Fragments:

// Retrieve the ViewModel associated with this Fragment
val viewModel: MyVewModel by viewModels { myFactory }

// Retrieve the ViewModel associated with the activity
val activityViewModel: MyVewModel by activityViewModels { myFactory }

Or, if you're accessing the ViewModel from your Activity itself, you'd use its by viewModels:

// In an Activity, you can retrieve a ViewModel scoped to the Activity
// by using viewModels
val viewModel: MyVewModel by viewModels { myFactory }

Upvotes: 5

Related Questions