Cannot resolve ViewModelProvider construction in a fragment?

后端 未结 4 1814
悲哀的现实
悲哀的现实 2021-02-19 05:28

I have been spending a lot of time trying to figure out why in the code below (towards the end), I get an error on ViewModelProvider(this). I also tried getActivity() instead of

4条回答
  •  星月不相逢
    2021-02-19 05:43

    The cleanest implementation must use Kotlin for its advanced functions. You can either create this kotlin code in a separate Kclass or leave this answer for future users that want to know how to do this in Kotlin. Basically we are initialising the ViewModel by lazy like this:

    Make sure you have this dependency:

    implementation "androidx.fragment:fragment-ktx:1.2.0"
    

    Create this helper function that accesses an internal fragment-ktx method that allows yo to create a ViewModel instance by lazy:

    @MainThread
    inline fun  Fragment.fragmentViewModel() =
        createViewModelLazy(
            VM::class,
            { this.viewModelStore },
            { ViewModelFactory(Database.getDatabase(requireContext().applicationContext)) }
        )
    

    Now create a ViewModelFactory using this official java example:

    https://github.com/android/architecture-components-samples/blob/master/BasicRxJavaSample/app/src/main/java/com/example/android/observability/ui/ViewModelFactory.java

    Or, here is the Kotlin variant:

    class ViewModelFactory(private val database: Database?) : ViewModelProvider.Factory {
    
        override fun  create(modelClass: Class): T {
    
            requireNotNull(database) { "Database must not be null" }
    
            return when {
    
                modelClass.isAssignableFrom(ItemSetupFragmentModel::class.java) -> {
                    ItemSetupFragmentModel() as T
                }
    
                else -> {
                    throw IllegalArgumentException("Unknown ViewModel class")
                }
            }
        }
    }
    

    And now go inside your fragment and simply initialise your ViewModel like this

    class ItemSetupFragment : Fragment() {
    
        private val model by viewModel()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            model.getKids().observe(this, users -> {
                // update UI
            });
        }
    }
    

    Hope this helps!

提交回复
热议问题