Cannot resolve ViewModelProvider construction in a fragment?

浪尽此生 提交于 2020-05-13 06:08:07

问题


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 'this', same issue. The error I get is "Cannot resolve constructor ..."


import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;



public class ItemSetupFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_setup, container, false);

        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ItemSetupFragmentModel model = new ViewModelProvider(this).get(ItemSetupFragmentModel.class);
        model.getKids().observe(this, users -> {
            // update UI
        });
    }
}


回答1:


Firstly you need to use the latest version of lifecycle extension. It should be:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0" 

or any updated version.

Then you should use requireActivity() instead of getActivity(). This way you will ensure that the activity is attached an not getting a NullPointerException.

ItemSetupFragmentModel model = new ViewModelProvider(requireActivity()).get(ItemSetupFragmentModel.class);



回答2:


You aren't using the latest library release in which the ViewModelProvider(@NonNull ViewModelStoreOwner owner) constructor was included. You are seeing the latest docs but not using the latest library version of ViewModel. You need to use

    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0' // For Java

or

    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' // For kotlin extension



回答3:


You should instantiate your viewModel by :

ItemSetupFragmentModel model = ViewModelProviders.of(this).get(ItemSetupFragmentModel.class);



回答4:


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 <reified VM : ViewModel> 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 <T : ViewModel> create(modelClass: Class<T>): 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<ItemSetupFragmentModel>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        model.getKids().observe(this, users -> {
            // update UI
        });
    }
}

Hope this helps!



来源:https://stackoverflow.com/questions/60070233/cannot-resolve-viewmodelprovider-construction-in-a-fragment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!