Home > Enterprise >  How to convert in kotlin view model factory to property delegation?
How to convert in kotlin view model factory to property delegation?

Time:06-09

I have this base class for view model factory :

class BaseViewModelFactory<T>(val creator: () -> T) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return creator() as T
    }
}

I want to convert it to delegation property something like this..

inline fun <reified T : ViewModel> ViewModel.lazyWithParams(noinline provider: () -> T): ReadOnlyProperty<ViewModel, T> {
    return ...
}

If not possible maybe as extension function example...

Thanks!

CodePudding user response:

Here's a way to do that:

class LazyViewModelDelegate<T: ViewModel>(
    private val viewModelClass: Class<T>,
    private val viewModelProducer: () -> T) {

    lateinit var provider: ViewModelProvider

    operator fun getValue(owner: ViewModelStoreOwner, property: KProperty<*>): T {
        if(!::provider.isInitialized) {
            provider = ViewModelProvider(owner, object : ViewModelProvider.Factory {
                //Unchecked cast because we only request a ViewModel of type T from this provider
                @Suppress("UNCHECKED_CAST")
                override fun <T : ViewModel> create(modelClass: Class<T>): T {
                    return viewModelProducer.invoke() as T
                }
            })
        }

        return provider.get(viewModelClass)
    }
}

inline fun <reified T: ViewModel> ViewModelStoreOwner.viewModelFactory(noinline factory: () -> T) =
    LazyViewModelDelegate(T::class.java, factory)

To use, put in your activity e.g.

private val viewModel by viewModelFactory {
    LoginActivityViewModel()
}

Though perhaps not the cleanest approach, it's possible to add parameters to the constructor of the viewmodel, the viewModel will be instantiated lazily when you first access it.

  • Related