Android create ViewModel with parameters without dagger
This post will go through the steps and code for creating ViewModel that contains parameters without using a dependency injection framework such as dagger hilt.
Here is a ViewModel which needs a parameter in order to instantiate it.
class MyViewModel( private val messageDataStore: MessageDataStore, ): ViewModel() { ... }
Here is factory class for instantiating ViewModels, ViewModelFactory.kt
/** * Factory for all ViewModels. */ @Suppress("UNCHECKED_CAST") class ViewModelFactory constructor( private val messageDataStore: MessageDataStore, owner: SavedStateRegistryOwner, defaultArgs: Bundle? = null ) : AbstractSavedStateViewModelFactory(owner, defaultArgs) { override funcreate( key: String, modelClass: Class , handle: SavedStateHandle ) = with(modelClass) { when { isAssignableFrom(MyViewModel::class.java) -> MyViewModel(messageDataStore) else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") } } as T }
Here is the application class with the required parameter for instantiating the ViewModel. In this case, it’s a custom data store instance MessageDataStore.
class MyApp : Application() { val messageDataStore: MessageDataStore get() = MessageDataStore.getInstance(this) }
Here is a file with extension functions for getting the ViewModelFactory in Activity and Fragment. ViewModelUtilExt.kt
fun AppCompatActivity.getViewModelFactory(savedInstanceState: Bundle?): ViewModelFactory { val messageDataStore = (applicationContext as MyApp).messageDataStore return ViewModelFactory(messageDataStore, this, savedInstanceState) } fun Fragment.getViewModelFactory(savedInstanceState: Bundle?): ViewModelFactory { val messageDataStore = (requireContext().applicationContext as MyApp).messageDataStore return ViewModelFactory(messageDataStore, this.requireActivity(), savedInstanceState) }
Getting the ViewModel in Activity.
class MainActivity : AppCompatActivity() { private lateinit var myViewModel: MyViewModel // Other code... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val vm by viewModels{ getViewModelFactory(savedInstanceState) } myViewModel = vm // Other code... } }
Getting the ViewModel in Fragment.
class MyFragment : Fragment() { private lateinit var myViewModel: MyViewModel //Other code... override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val vm by activityViewModels{ getViewModelFactory(savedInstanceState) } myViewModel = vm //Other code... } }
Search within Codexpedia
Custom Search
Search the entire web
Custom Search
Related Posts