DEV Community

Cover image for Implement ViewModelProvider.Factory Interface for Custom ViewModel / AndroidViewModel Factory Creation
Vincent Tsen
Vincent Tsen

Posted on • Edited on • Originally published at vtsen.hashnode.dev

5 1

Implement ViewModelProvider.Factory Interface for Custom ViewModel / AndroidViewModel Factory Creation

We do NOT need to extend ViewModelProvider.NewInstanceFactory (for ViewModel) or ViewModelProvider.AndroidViewModel (for AndroidViewModel)

In my previous post - Recommended Ways To Create ViewModel or AndroidViewModel, I mentioned that in order to create ViewModel, we need to create a factory that extends ViewModelProvider.NewInstanceFactory() and to create AndroidViewModel, we need to extend ViewModelProvider.AndroidViewModelFactory().

Well, it works, but it is unnecessary. We can just implement the ViewModelPrvoider.Factory interface directly for both of them.

ViewModelProvider.NewInstanceFactory()

class MyViewModelFactory(private val repository: Repository)
    : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
Enter fullscreen mode Exit fullscreen mode

Can be replaced by ViewModelProvider.Factory

class MyViewModelFactory(private val repository: Repository)
    : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
            return MyViewModel(repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
Enter fullscreen mode Exit fullscreen mode

ViewModelProvider.AndroidViewModelFactory(app)

class MyAndroidViewModelFactory(
    private val app: Application,
    private val repository: Repository)
    : ViewModelProvider.AndroidViewModelFactory(app) {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(
                MyAndroidViewModel::class.java)) {

            return MyAndroidViewModel(app, repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
Enter fullscreen mode Exit fullscreen mode

Can be replaced by ViewModelProvider.Factory

class MyAndroidViewModelFactory(
    private val app: Application,
    private val repository: Repository)
    : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        if (modelClass.isAssignableFrom(
                MyAndroidViewModel::class.java)) {

            return MyAndroidViewModel(app, repository) as T
        }

        throw IllegalArgumentException("Unknown ViewModel class")
    }
}
Enter fullscreen mode Exit fullscreen mode

Since both ViewModelProvider.NewInstanceFactory()and ViewModelProvider.AndroidViewModelFactory() implementViewModelPrvoider.Factory interface, we can just implement the ViewModelPrvoider.Factory interface directly to create the custom ViewModel / AndroidViewModel factory which takes in different constructor parameters. We don't need an additional layer here.

Implement_ViewModelProvider_Factory_Interface_01.jpg

By the way, this is the feedback that I get from medium suggesting another better approach is to use Hilt Dependency Injection instead of using factory to create the custom ViewModel, which is also known as constructor dependency injection.

I personally have not used Hilt yet, and will definitely learn and blog about it.

[Updated - July 04, 2022]: I have played around with Hilt a bit and here are the simple steps to implement Hilt into your app.


Originally published at https://vtsen.hashnode.dev.

Heroku

Deliver your unique apps, your own way.

Heroku tackles the toil — patching and upgrading, 24/7 ops and security, build systems, failovers, and more. Stay focused on building great data-driven applications.

Learn More

Top comments (0)

👋 Kindness is contagious

Dive into this informative piece, backed by our vibrant DEV Community

Whether you’re a novice or a pro, your perspective enriches our collective insight.

A simple “thank you” can lift someone’s spirits—share your gratitude in the comments!

On DEV, the power of shared knowledge paves a smoother path and tightens our community ties. Found value here? A quick thanks to the author makes a big impact.

Okay