How to use ViewModel architecture components inside a RecyclerView adapter?

I have several ViewHolders that work as split views inside a vertical RecyclerView. I am training with the new ViewModel Architecture Components.

inside my ViewModel I have some MutableLiveData lists that I want to watch. but what can i call

ViewModelProviders.of((AppCompatActivity)getActivity()).get(FilterViewModel.class)

and

mFilterViewModel.getCountries().observe(this, new Observer<ArrayList<TagModel>>() {
            @Override
            public void onChanged(@Nullable ArrayList<TagModel> tagModels) {

            }
        });

without leakage of activity or maintaining activity inside the adapter.

my ViewModel

public class FilterViewModel extends ViewModel {

private final MutableLiveData<ArrayList<TagModel>> mCountries;
private final MutableLiveData<ArrayList<TagModel>> mSelectedCountryProvinceList;
private final MutableLiveData<ArrayList<TagModel>> mDistanceList;

public FilterViewModel(){

    mCountries = new MutableLiveData<>();
    mSelectedCountryProvinceList = new MutableLiveData<>();
    mDistanceList = new MutableLiveData<>();

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() {
        @Override
        public void update(TagSearchList object) {
            mCountries.setValue(object.getCountries());
        }

        @Override
        public void update(int id, TagSearchList object) {
            if (id == 5){
                TagStore.getInstance().unSubcribe(this);
                update(object);
            }
        }

        @Override
        public void error(String error) {

        }
    }).get(5,"parent");

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() {
        @Override
        public void update(TagSearchList object) {
            mSelectedCountryProvinceList.setValue(object.toList());
        }

        @Override
        public void update(int id, TagSearchList object) {
            if (id == 6){
                TagStore.getInstance().unSubcribe(this);
                update(object);
            }
        }

        @Override
        public void error(String error) {

        }
    }).get(6,"parent");

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() {
        @Override
        public void update(TagSearchList object) {
            mDistanceList.setValue(object.toList());
        }

        @Override
        public void update(int id, TagSearchList object) {
            if (id == 51){
                TagStore.getInstance().unSubcribe(this);
                update(object);
            }
        }

        @Override
        public void error(String error) {

        }
    }).get(51,"parent");

}

public void selectCountry(final TagModel country){
    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() {
        @Override
        public void update(TagSearchList object) {
            mSelectedCountryProvinceList.setValue(object.toList());
        }

        @Override
        public void update(int id, TagSearchList object) {
            if (id == country.getId()){
                TagStore.getInstance().unSubcribe(this);
                update(object);
            }
        }

        @Override
        public void error(String error) {

        }
    }).get(country.getId(),"parent");
}

public LiveData<ArrayList<TagModel>> getCountries(){
    return mCountries;
}

public LiveData<ArrayList<TagModel>> getDistances(){
    return mDistanceList;
}

public LiveData<ArrayList<TagModel>> getProvinces(){
    return mSelectedCountryProvinceList;
}

}

+6
source share
2 answers

My solution to this problem:

  • create a new variable (ViewModel) for the layout (fragment or layout of the action)
  • viewModel ViewModelProviders
  • , recyclerView MutableLiveData recyclerView , .

, . ,

0

. , :

  • ViewModelProvider:

    ViewModelProvider provider = ViewModelProviders.of(this);

  • ,

  • ViewHolder , FilterBinding

    super(binding.getRoot());

  • onCreateViewHolder , , DataBindingUtil.inflate(...) ViewHolder, ;

  • ViewHolder , TagModel ( , , y , ) :

    if (mBindings == null) { FilterViewModel vm = viewModelProvider.get(FilterViewModel.class); /*or instantiate? I am not sure about caching here, honestly. If you chose instantiating, then passing ViewModelProvider to the adapter is not needed*/ mBindings.setViewModel(vm); } mBindings.getViewModel(setItem(item)); mBindings.executePendingBindings();

  • , , onBindViewHolder (...)

, , , , .

0

All Articles