Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create view model factory for AndroidViewModel?

I need to pass value when the view model is created (userData), so I need to create a view model factory

here is my viewModel, I need application and userData to init this ScoreViewModel

class ScoreViewModel(application: Application, userData: UserKM) : AndroidViewModel(application) {



}

but now I am confused how to pass application when I create viewModel factory

class ScoreViewModelFactory(private val userData: UserKM) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) {

            return ScoreViewModel(userData = userData,application = ?????? ) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }

}

what should I do ?

like image 650
sarah Avatar asked Mar 21 '20 09:03

sarah


People also ask

What is ViewModel provider Factory?

The factory is responsible to create your instance of ViewModel. If your ViewModel has dependencies and you want to test your ViewModel then you should create your own ViewModelProvider. Factory and passed dependency through ViewModel constructor and give value to the ViewModelProvider.

Who creates the instance of a ViewModel?

Creating a ViewModel instance in your activityViewModelProvider is a utility class for ViewModelStore . It internally refers to ViewModelStore to return an existing instance of the ViewModel if it exists — otherwise, it creates a new one. ViewModelStore internally keeps track of the ViewModel s using a HashMap .


1 Answers

You can have something like this :

class Factory(val app: Application) : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(NewsViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return NewsViewModel(app) as T
            }
            throw IllegalArgumentException("Unable to construct viewmodel")
        }
    }

In your activity or fragment you have :

/**
     * One way to delay creation of the viewModel until an appropriate lifecycle method is to use
     * lazy. This requires that viewModel not be referenced before onActivityCreated, which we
     * do in this Fragment.
     */
    private val viewModel: NewsViewModel by lazy {
        val activity = requireNotNull(this.activity) {
            "You can only access the viewModel after onActivityCreated()"
        }
        ViewModelProviders.of(this, NewsViewModel.Factory(activity.application))
            .get(NewsViewModel::class.java)
    }

And here your viewModel can look like :

class NewsViewModel(application: Application) : AndroidViewModel(application)

For more detail you can look at : https://github.com/Ali-Rezaei/News-Cache/blob/master/app/src/main/java/com/sample/android/news/viewmodels/NewsViewModel.kt

like image 199
Ali Avatar answered Sep 22 '22 12:09

Ali