0

I'm trying to initialize viewmodel in Fragment but each time I want to pass the interface in my viewmodel constructor it throws the error Cannot create an instance of class ViewModel Also I don't have any problem in kotlin-kapt or any lifecycle annotations

here is my ViewModel class

class SettingsViewModel (
       var settingsView: SettingsView
    ) : ViewModel(){ }

and here is my fragment where i want to initialize the viewmodel

class SettingsFragment : Fragment(), SettingsView {

     var viewmodel :SettingsViewModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

         viewmodel = ViewModelProviders.of(this).get(SettingsViewModel(this)::class.java)

        val binding =
            DataBindingUtil.inflate<FragmentSettingsBinding>(inflater, R.layout.fragment_settings, container, false)
                .apply{}


        return binding.root
    }
Al Walid Ashik
  • 1,545
  • 20
  • 32

2 Answers2

6

When you are initialising the ViewModel through ViewModelProviders without a factory, this means that you can only instantiate a ViewModel which has no constructor arguments. Like this:

viewmodel = ViewModelProviders.of(this).get(SettingsViewModel::class.java)

Notice that you cannot pass arguments to a .class call because you are not calling the constructor

Since your ViewModel has constructor arguments you need to implement a ViewModelProvider.Factory in order to be able to retrieve its instance with given parameters.

Here is a reference to android devs: https://developer.android.com/reference/android/arch/lifecycle/ViewModelProvider

Here refers to an article that can give you a insight on how to implement the factory: https://medium.com/@marco_cattaneo/android-viewmodel-and-factoryprovider-good-way-to-manage-it-with-dagger-2-d9e20a07084c

Ricardo
  • 9,136
  • 3
  • 29
  • 35
1

in my case, I forget to add

AndroidInjection.inject(this); 

in my activity like this :

 @Override
    public void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
Sana Ebadi
  • 6,656
  • 2
  • 44
  • 44