Home > Software design >  How do you call a fragment method from an adapter?
How do you call a fragment method from an adapter?

Time:04-12

I would like to refresh my recycle view when a user taps a button, the problem is my recycle view is inside a fragment, and my user interface is being updated from my OnBindViewHolder method. So, my question is how do you call a method that's inside a fragment, from an Adapter. I would like to call my downloadCartData() from my Cart_Fragment when the user clicks on plusImageView from my adapter. I found some answers on stack overflow that says to use an interface, but I don't understand what's happening or how to apply it to my code.

public class CartAdapter extends RecyclerView.Adapter<CartAdapter.ViewHolder> {
    private List<CartModel> cartArrayList;
    private Context ct;
    public int count = 1;
    private String loggedInUserId;


    public CartAdapter(List<CartModel> cartArrayList, Context ct) {
        this.cartArrayList = cartArrayList;
        this.ct = ct;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") final int position) {
        holder.produceName.setText(cartArrayList.get(position).getProductName());
        Log.i("productname", cartArrayList.get(position).getProductName());

        holder.producePrice.setText("$"   cartArrayList.get(position).getItemPrice());
        holder.plusImageView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                getCurrentUserUid();
                count = count   1;
                FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if(task.isSuccessful()){
                            holder.middleQUanityTv.setText(count   "");
//                            Cart_Fragment cart_fragment = new Cart_Fragment();
//                            cart_fragment.callMethod();
                            //



                        }
                    }
                });

            }
        });


        //Log.i("IMAGES", productArrayList.get(position).getProductImage());
        Glide.with(ct)
                .load(cartArrayList.get(position).getProductImage())
                .centerCrop()
                .into(holder.productImage);


    }

    @Override
    public int getItemCount() {
        return cartArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView produceName, producePrice, middleQUanityTv;
        private ImageView productImage, plusImageView, minusImageView;


        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            produceName = itemView.findViewById(R.id.itemNameTv);
            producePrice = itemView.findViewById(R.id.priceTv);
            productImage = itemView.findViewById(R.id.productImageView);
            plusImageView = itemView.findViewById(R.id.plusImageView);
            middleQUanityTv = itemView.findViewById(R.id.middleQuanaityTv);


        }


    }

    //hide ui elements here..
    public void getCurrentUserUid() {
        FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        if (firebaseUser != null) {
            loggedInUserId = firebaseUser.getUid(); //Do what you need to do with your uid
            Log.i("loggedInUserUid", loggedInUserId);


        }

    }

}


 public void downloadCartData() {
        cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    if (data.exists()) {

                        //get the item prices to add to hashmap.
                        String price = data.child("itemPrice").getValue().toString();
                        String quantity = data.child("quantity").getValue().toString();

                        priceArrayList.add(price);
                        quantityArrayList.add(quantity);

                        cartModel = data.getValue(CartModel.class);
                        cartModelArrayList.add(cartModel);
                        LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
                        cartRecyleView.setLayoutManager(horizontalLayoutManager);
                        cartAdapter = new CartAdapter(cartModelArrayList, getContext());
                        cartRecyleView.setAdapter(cartAdapter);

                    } else {
                        Log.i("error", "Error Loading JSON data..");

                    }

                }
                calculatePrice(priceArrayList, quantityArrayList);


                Log.i("priceArrayList", priceArrayList   "");
                Log.i("quanityArrayList", quantityArrayList   "");


            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                String error = databaseError.getDetails();
                Log.i("error", error);

            }
        });

    }

CodePudding user response:

You have heard right from the other stack overflow posts that you can use interface to call the method of the fragment from the adapter.

First you have to create a interface and define the method name in the interface.

interface DownloadCart{  

    void downloadCartData();  

}  

After creating this interface you need to implement this interface into the fragment where your recycler view is declared.

class Cart_Fragment implements DownloadCart{  

After implementing this interface into the class it will show you red line in android studio. it will require to add the method of the interface into your fragment. add your code of the downloadCartData into this interface method body in your fragment.

void downloadCartData(){
 cartDb.child("Cart").child(loggedInUserId).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    if (data.exists()) {

                        //get the item prices to add to hashmap.
                        String price = data.child("itemPrice").getValue().toString();
                        String quantity = data.child("quantity").getValue().toString();

                        priceArrayList.add(price);
                        quantityArrayList.add(quantity);

                        cartModel = data.getValue(CartModel.class);
                        cartModelArrayList.add(cartModel);
                        LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
                        cartRecyleView.setLayoutManager(horizontalLayoutManager);
                        cartAdapter = new CartAdapter(cartModelArrayList, getContext());
                        cartRecyleView.setAdapter(cartAdapter);

                    } else {
                        Log.i("error", "Error Loading JSON data..");

                    }

                }
                calculatePrice(priceArrayList, quantityArrayList);


                Log.i("priceArrayList", priceArrayList   "");
                Log.i("quanityArrayList", quantityArrayList   "");


            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                String error = databaseError.getDetails();
                Log.i("error", error);

            }
        });

}  

Create on object of the interface into your adapter.

DownloadCart inf;

Define your adapter constructor like this and pass your interface object into the adapter call.

public CartAdapter(List<CartModel> cartArrayList, Context ct, DownloadCart inf) {

        this.cartArrayList = cartArrayList;
        this.ct = ct;
        this.inf = inf;

    }

After that on bind view holder call your fragment method into the adapter by using the interface object. it will call the method from the fragment.

  @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, @SuppressLint("RecyclerView") final int position) {
        holder.produceName.setText(cartArrayList.get(position).getProductName());
        Log.i("productname", cartArrayList.get(position).getProductName());

        holder.producePrice.setText("$"   cartArrayList.get(position).getItemPrice());
        holder.plusImageView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                getCurrentUserUid();
                count = count   1;
                FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if(task.isSuccessful()){
                            holder.middleQUanityTv.setText(count   "");
                               inf.downloadCartData();



                        }
                    }
                });

            }
        });


        //Log.i("IMAGES", productArrayList.get(position).getProductImage());
        Glide.with(ct)
                .load(cartArrayList.get(position).getProductImage())
                .centerCrop()
                .into(holder.productImage);


    }

Tadaaa!!! and your method from fragment is called from adapter.

CodePudding user response:

Pass the Cart_Fragment inside your adapter Constructor, then simply call the method you're trying to reference from your onClickListener by referencing the passed Fragment.

private Cart_Fragment cart_fragment = new Cart_Fragment();

    public CartAdapter(List<CartModel> cartArrayList, Context ct, Cart_Fragment cart_fragment) {
        this.cartArrayList = cartArrayList;
        this.ct = ct;
        this.cart_fragment = cart_fragment;
    }

  @Override
            public void onClick(View view) {
                getCurrentUserUid();
                count = count   1;
            

FirebaseDatabase.getInstance().getReference("Cart").child(loggedInUserId).child(cartArrayList.get(position).getTimestamp()).child("quantity").setValue(count).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if(task.isSuccessful()){
                        holder.middleQUanityTv.setText(count   "");

                        Cart_Fragment cart_fragment = new Cart_Fragment();
                        cart_fragment.callMethod();









                    }
                }
            });

        }
    });
  • Related