Search code examples
androidmvvmviewmodelandroid-components

Android ViewModel additional arguments


Is there a way to pass additional argument to my custom AndroidViewModel constructor except Application context. Example:

    public class MyViewModel extends AndroidViewModel {
        private final LiveData<List<MyObject>> myObjectList;
        private AppDatabase appDatabase;

        public MyViewModel(Application application, String param) {
            super(application);
            appDatabase = AppDatabase.getDatabase(this.getApplication());
            
            myObjectList = appDatabase.myOjectModel().getMyObjectByParam(param);
        }
    }

And when I want to user my custom ViewModel class I use this code in my fragment:

    MyViewModel myViewModel = ViewModelProvider.of(this).get(MyViewModel.class)

So I don't know how to pass additional argument String param into my custom ViewModel. I can only pass Application context, but not additional arguments. I would really appreciate any help. Thank you.

Edit: I've added some code. I hope it's better now.


Solution

  • You need to have a factory class for your ViewModel.

    public class MyViewModelFactory implements ViewModelProvider.Factory {
        private Application mApplication;
        private String mParam;
    
    
        public MyViewModelFactory(Application application, String param) {
            mApplication = application;
            mParam = param;
        }
    
    
        @Override
        public <T extends ViewModel> T create(Class<T> modelClass) {
            return (T) new MyViewModel(mApplication, mParam);
        }
    }
    

    And when instantiating the view model, you do like this:

    MyViewModel myViewModel = new ViewModelProvider(this, new MyViewModelFactory(this.getApplication(), "my awesome param")).get(MyViewModel.class);
    

    For kotlin, you may use delegated property:

    val viewModel: MyViewModel by viewModels { MyViewModelFactory(getApplication(), "my awesome param") }
    

    There's also another new option - to implement HasDefaultViewModelProviderFactory and override getDefaultViewModelProviderFactory() with the instantiation of your factory and then you would call ViewModelProvider(this) or by viewModels() without the factory.