I am programing a app in kotlin using MVVM structure and trying to instantiate my viewmodel through my factory... though im getting a trouble when i start app that says this java.lang.RuntimeException: Cannot create an instance of class com.example.paperseller.ui.menu.ViewModels.AuthViewModel
i have no clue at all why im getting this trouble. My code looks like this
Fragment
package com.example.paperseller.ui.menu
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.example.paperseller.Data.User
import com.example.paperseller.R
import com.example.paperseller.databinding.LoginRegisterFragmentBinding
import com.example.paperseller.ui.menu.ViewModels.AuthViewModel
class LoginRegister_fragment : Fragment(R.layout.login_register_fragment) {
private var _binding : LoginRegisterFragmentBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
_binding = LoginRegisterFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initializeUI()
}
private fun initializeUI()
{
val factory = InjectorUtils.providePaperSellerViewModelFactory()
val viewModel : AuthViewModel by viewmodels()
viewModel.message.observe(this)
{
message ->
Toast.makeText(requireActivity(), message, Toast.LENGTH_LONG).show()
}
binding.registerButton.setOnClickListener()
{
val user = User(binding.emailText.text.toString(), binding.passwordText.text.toString());
viewModel.register(user)
}
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
ViewModelFactory
package com.example.paperseller.ui.menu.ViewModelFactory
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.example.paperseller.Data.PaperSellerRepository
import com.example.paperseller.ui.menu.ViewModels.AuthViewModel
class PaperSellerViewModelFactory(private val paperSellerRepository: PaperSellerRepository) : ViewModelProvider.NewInstanceFactory()
{
@Suppress("UNCHECKED_CAST")
override fun <T:ViewModel?> create(modelClass: Class<T>):T{
return AuthViewModel(paperSellerRepository) as T
}
}
I tried to follow this tutorial but he is using Kotlin synthetics and what i understand that has been deprecated. Here is the link anyways https://resocoder.com/2018/09/07/mvvm-on-android-crash-course-kotlin-android-architecture-components/
CodePudding user response:
Your ViewModel
takes in a repository and since then You have to use the ViewModelFactory
. You can either use ViewModelProvider
:
val factory = InjectorUtils.providePaperSellerViewModelFactory()
val viewModel = ViewModelProvider(
this,
factory)
.get(AuthViewModel::class.java)
or, as @IR42 has pointed out, You can use viewModels
delegate:
val viewModel: AuthViewModel by viewModels { factory }