I am developing an E-commerce app which displays the users products they have added to their carts, inside a recycleview. I would like for the user to be able to increase the quantity for an item when they click a button by 1, which I have successfully implemented, but the problem that I am having is that the widget is inside an adapter class, I would need to access it inside of my Cartfragment in order to perform the necessary function such as update my recycle view with the user edited quantity, So the main question I am having is how do you access a UI element from an adapter view holder class inside of a fragment?
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);
plusImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
count = count 1;
middleQUanityTv.setText(count "");
}
});
}
public class Cart_Fragment extends Fragment {
private View layoutView;
private RecyclerView cartRecyleView;
private CartModel cartModel;
private ArrayList<CartModel> cartModelArrayList;
private DatabaseReference cartDb;
private CartAdapter cartAdapter;
private String loggedInUserId;
private TextView subTotalTv, shippingTv, totalTv;
private ArrayList<String> priceArrayList, quantityArrayList;
private double shippingCost = 10.00;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
layoutView = inflater.inflate(R.layout.cart_layout, container, false);
setUpFirebase();
findViewsById();
initObject();
getCurrentUserUid();
return layoutView;
}
public void findViewsById() {
cartRecyleView = layoutView.findViewById(R.id.cartRecycleView);
subTotalTv = layoutView.findViewById(R.id.subtotalTv);
shippingTv = layoutView.findViewById(R.id.shippingTv);
totalTv = layoutView.findViewById(R.id.totalTv);
cartRecyleView.addOnItemTouchListener(
new RecyclerItemClickListener(getContext(), cartRecyleView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
// do whatever
Log.i("position",position "");
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
}
public void initObject() {
cartModelArrayList = new ArrayList<>();
priceArrayList = new ArrayList<>();
quantityArrayList = new ArrayList<>();
}
public void setUpFirebase() {
cartDb = FirebaseDatabase.getInstance().getReference();
cartDb.keepSynced(true);
}
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);
downloadCartData();
}
}
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);
}
});
}
//calculate total price of items in user cart.
public void calculatePrice(ArrayList<String> priceArrayList, ArrayList<String> quantityArrayList) {
//Convert String Array to double..
double[] priceArrayDouble = new double[priceArrayList.size()];
double[] quantityArrayDouble = new double[quantityArrayList.size()];
for (int i = 0; i < priceArrayList.size(); i ) {
priceArrayDouble[i] = Double.parseDouble(priceArrayList.get(i));
}
for (int i = 0; i < quantityArrayList.size(); i ) {
quantityArrayDouble[i] = Double.parseDouble(quantityArrayList.get(i));
}
//do calculations.
double sum = 0.0;
for (int i = 0; i < quantityArrayDouble.length; i ) {
sum = quantityArrayDouble[i] * priceArrayDouble[i];
}
Log.i("sum", sum "");
//populate ui elements..
//format decimal.
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " df.format(sum));
subTotalTv.setText("$" df.format(sum));
//10.00 is for shipping
double totalCost = shippingCost sum;
totalTv.setText("$" df.format(totalCost));
}
}
CodePudding user response:
Implement callback interface to your fragment
Then inject your fragment as callback into the adapter, viewholder
interface OnCartItemCallback {
void increaseQuantity(Product product);
}
class Adapter {
OnCartItemCallback onCartItemCallback;
//some code
viewHolder.setOnCartItemCallback(onCartItemCallback);
}
class ViewHolder {
OnCartItemCallback onCartItemCallback;
//some code
plusImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onCartItemCallback.increaseQuantity(product);
}
});
}
class CartFragment implements OnCartItemCallback {
//some code
adapter.setOnCartItemCallback(this);
//some code
@Override
void increaseQuantity(Product product){
//do some stub to update UI
}
}
CodePudding user response:
First off- your adapter shouldn't be an Adapter<Item>
. It should be an Adapter<LineItem>
where LineItem has a reference to the Item and a quantity field. That's closer to what you actually have.
Secondly- you would NEVER directly update the UI of an item in a RecyclerView from outside logic. You update the model, then tell the recyclerView to refresh itself via notifyItemChanged or notifyDataSetChanged.