how to use Architecture Components ViewModel inside RecyclerView Adapter?

前端 未结 3 2000
慢半拍i
慢半拍i 2021-02-02 08:16

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

Inside my ViewMo

相关标签:
3条回答
  • 2021-02-02 08:45

    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);
    
    }
    
    }
    
    0 讨论(0)
  • 2021-02-02 08:46

    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.

    0 讨论(0)
  • 2021-02-02 08:51

    My solution to this issue is;

    • 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

    here you mut be careful not to create adapter instance in observe method. if you create it in observe method, it will make leaks

    0 讨论(0)
提交回复
热议问题