Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use Architecture Components ViewModel inside RecyclerView Adapter?

I have multiple ViewHolders that work as separated views inside a vertical RecyclerView. I'm practicing with the new Architecture Components ViewModel.

Inside my ViewModel I have a couple of MutableLiveData lists that i want to observe, but how 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 leaking the activity or save the 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; } 
like image 532
quantum apps Avatar asked Jun 12 '17 08:06

quantum apps


People also ask

How do I use Viewmodelprovider adapter?

create a new variable(ViewModel) for the layout (fragment or activity layout) in your activity or fragment get the instance of your viewModel with ViewModelProviders. hold the data which fills your recyclerView in MutableLiveData and observe it and fill the adapter of recyclerView with the value you observed.


2 Answers

I am using Room Persistence library. Below is my code for recyclerview adapter using MVVM.

You can see CartViewModel and I have initialized it into the constructor. The constructor gets the context from the activity, and I have cast it into FragmentActivity.

private CartViewModel cartViewModel;  public CartListAdapter(Context context, List<CartModel> cartModels) {         this.context = context;         this.cartModels = cartModels;          cartViewModel = ViewModelProviders.of((FragmentActivity) context).get(CartViewModel.class);     } 

Here is my full adapter class. I hope it will help.

public class CartListAdapter extends RecyclerView.Adapter<CartListAdapter.CartListViewHolder> {  private static final String TAG = "CartListAdapter";  private Context context; private List<CartModel> cartModels;  private Double totalQuantity = 0.0;  private CartViewModel cartViewModel;  public CartListAdapter(Context context, List<CartModel> cartModels) {     this.context = context;     this.cartModels = cartModels;      cartViewModel = ViewModelProviders.of((FragmentActivity) context).get(CartViewModel.class); }  @NonNull @Override public CartListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {     return new CartListViewHolder(LayoutInflater.from(context).inflate(R.layout.list_all_cart_item,parent,false)); }  @Override public void onBindViewHolder(@NonNull CartListViewHolder holder, int position) {      CartModel cartModel = cartModels.get(position);      Glide.with(context)             .load(cartModel.getPPICLocate())             .into(holder.cartItemImage);      holder.tvCartProductName.setText(cartModel.getProductName());     holder.tvCartProductCategory.setText(cartModel.getPCategorySubID());     holder.tvCartProductPrice.setText(cartModel.getPPriceSales());     holder.etCartProductQuantity.setText(cartModel.getPQuantity());      holder.btnCartPQtIncrease.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View view) {              totalQuantity = Double.valueOf(holder.etCartProductQuantity.getText().toString());             totalQuantity = totalQuantity+1;             cartModel.setPQuantity(totalQuantity.toString());             updateCart(cartModel);         }     });      holder.btnCartPQtDecrease.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View view) {              totalQuantity = Double.valueOf(holder.etCartProductQuantity.getText().toString());             totalQuantity = totalQuantity-1;             cartModel.setPQuantity(totalQuantity.toString());             updateCart(cartModel);           }     }); }    @Override public int getItemCount() {     return cartModels.size(); }  public class CartListViewHolder extends RecyclerView.ViewHolder{      private ImageView cartItemImage;     private TextView tvCartProductName,tvCartProductCategory,tvCartProductPrice,             etCartProductQuantity,tvCartProductPrevPrice;     private ImageButton btnCartPQtIncrease,btnCartPQtDecrease;      public CartListViewHolder(@NonNull View itemView) {         super(itemView);          cartItemImage= itemView.findViewById(R.id.cartItemImage);         tvCartProductName= itemView.findViewById(R.id.tvCartProductName);         tvCartProductCategory= itemView.findViewById(R.id.tvCartProductCategory);         tvCartProductPrice= itemView.findViewById(R.id.tvCartProductPrice);         etCartProductQuantity= itemView.findViewById(R.id.etCartProductQuantity);         tvCartProductPrevPrice= itemView.findViewById(R.id.tvCartProductPrevPrice);         btnCartPQtIncrease= itemView.findViewById(R.id.btnCartPQtIncrease);         btnCartPQtDecrease= itemView.findViewById(R.id.btnCartPQtDecrease);      } }  public void addItems(List<CartModel> cartModels) {     this.cartModels = cartModels;     notifyDataSetChanged(); }  private void updateCart(CartModel cartModel){     String tqt = String.valueOf(cartModel.getPQuantity());     Log.d(TAG, "updateQuantity: "+tqt);     /*cartRepository.updateCartRepo(cartModel);*/     cartViewModel.updateCartItemVM(cartModel);  }  } 
like image 132
Wasi Sadman Avatar answered Sep 20 '22 17:09

Wasi Sadman


You could create an OnClickListener interface instead, then implement the onClick method (defined in your interface) in your fragment or activity where you have access to your view model.

like image 37
David O'Dwyer Avatar answered Sep 19 '22 17:09

David O'Dwyer