Android ViewModel arguments supplémentaires

Existe-t-il un moyen de passer un argument supplémentaire à mon constructeur AndroidViewModel Personnalisé, sauf le contexte de L'Application. Exemple:

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);
    }
}

Et quand je veux utiliser ma classe ViewModel personnalisée, j'utilise ce code dans mon fragment:

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

Donc je ne sais pas comment passer un argument supplémentaire String param dans Mon ViewModel personnalisé. Je ne peux passer que le contexte de L'Application, mais pas d'arguments supplémentaires. Je serais vraiment reconnaissant de toute aide. Merci.

Edit: j'ai ajouté du code. J'espère que c'est mieux maintenant.

21
demandé sur Mario Rudman 2017-09-18 19:17:47

2 réponses

Vous devez avoir une classe factory pour votre ViewModel.

public class MyViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    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);
    }
}

Et lors de l'instanciation du modèle de vue, vous faites comme ceci:

MyViewModel myViewModel = ViewModelProviders.of(this, new MyViewModelFactory(this.getApplication(), "my awesome param")).get(MyViewModel.class);
48
répondu mlyko 2018-05-17 17:50:48

Pour une usine partagée entre plusieurs modèles de vues différents, j'étends la réponse de mlyko comme ceci:

public class MyViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    private Application mApplication;
    private Object[] mParams;

    public MyViewModelFactory(Application application, Object... params) {
        mApplication = application;
        mParams = params;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        if (modelClass == ViewModel1.class) {
            return (T) new ViewModel1(mApplication, (String) mParams[0]);
        } else if (modelClass == ViewModel2.class) {
            return (T) new ViewModel2(mApplication, (Integer) mParams[0]);
        } else if (modelClass == ViewModel3.class) {
            return (T) new ViewModel3(mApplication, (Integer) mParams[0], (String) mParams[1]);
        } else {
            return super.create(modelClass);
        }
    }
}

Et instanciation des modèles de vue:

ViewModel1 vm1 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), "something")).get(ViewModel1.class);
ViewModel2 vm2 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), 123)).get(ViewModel2.class);
ViewModel3 vm3 = ViewModelProviders.of(this, new MyViewModelFactory(getApplication(), 123, "something")).get(ViewModel3.class);

Avec différents modèles de vue ayant des constructeurs différents.

2
répondu rzehan 2018-05-16 14:53:27