1 Answer. Show activity on this post. Yes it is perfectly normal for a RecyclerView to call onBindViewHolder() multiple times. A RecyclerView only creates minimum number of Views needed to fill the screen.
A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View. findViewById(int) results.
My code is as shown below:
public class PopularItemsAdapter extends RecyclerView.Adapter<PopularItemsAdapter.MyViewHolder>
implements MyCartListener {
private Context mContext;
private List<FoodTruckItem> foodTruckItemList;
private boolean isClickable = false;
private OnItemClickListener listener;
private List<FoodtruckInfo> foodtruckInfoList = new ArrayList<>();
private List<FoodTruckItem> sessionItem = new ArrayList<>();
private boolean isConflictResolved = false;
public int position = -1;
@Override
public void itemUpdated(int quantity, String itemId) {
for (int i = 0; i < foodTruckItemList.size(); i++) {
if (itemId.equals(foodTruckItemList.get(i).getItemId())) {
foodTruckItemList.get(i).setItemQuantityOrdered(quantity);
// notifyDataSetChanged();
}
}
}
@Override
public void itemRemoved(String itemId) {
for (int j = 0; j < foodTruckItemList.size(); j++) {
if (itemId.equals(foodTruckItemList.get(j).getItemId())) {
foodTruckItemList.remove(j);
// notifyDataSetChanged();
}
}
}
public void addConflictItem(int position) {
isConflictResolved = true;
notifyItemChanged(position);
}
public interface OnItemClickListener {
void onItemClick(FoodTruckItem foodTruckItem, FoodtruckInfo foodtruckInfo);
void showSnackBar(int items, boolean added, int position);
void showRestaurentClosed();
void showWarningDialog(int position);
}
public void addFoodInfo(List<FoodtruckInfo> foodtruckInfos) {
foodtruckInfoList.addAll(foodtruckInfos);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView itemName, foodPrice, addText, quantityText, addQuantity, removeQuantity;
public ImageView itemImage, itemTag;
public LinearLayout addLayout;
public MyViewHolder(View view) {
super(view);
itemTag = (ImageView) view.findViewById(R.id.itemTag);
itemImage = (ImageView) view.findViewById(R.id.itemImage);
itemName = (TextView) view.findViewById(R.id.itemName);
foodPrice = (TextView) view.findViewById(R.id.foodPrice);
addText = (TextView) view.findViewById(R.id.addText);
addLayout = (LinearLayout) view.findViewById(R.id.addLayout);
quantityText = (TextView) view.findViewById(R.id.quantityText);
addQuantity = (TextView) view.findViewById(R.id.addQuantity);
removeQuantity = (TextView) view.findViewById(R.id.removeQuantity);
view.setOnClickListener(this);
}
@Override
public void onClick(View view) {
FoodtruckInfo foodtruckInfo = new FoodtruckInfo();
//passing the clicked position to the parent class
for (FoodtruckInfo info : foodtruckInfoList) {
if (info.getItemId().equals(foodTruckItemList.get(getAdapterPosition()).getItemId())) {
foodtruckInfo = info;
}
}
listener.onItemClick(foodTruckItemList.get(getAdapterPosition()), foodtruckInfo);
}
}
public PopularItemsAdapter(Context mContext, List<FoodTruckItem> foodTruckItemList, OnItemClickListener listener) {
this.mContext = mContext;
this.foodTruckItemList = foodTruckItemList;
this.listener = listener;
MyCart.getInstance().addListener(this);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_view_popular_items, parent, false);
return new MyViewHolder(itemView);
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final FoodTruckItem foodTruckItem = foodTruckItemList.get(position);
if (SessionManager.get(mContext).getFoodTruckItemList() != null) {
sessionItem = SessionManager.get(mContext).getFoodTruckItemList();
for (FoodTruckItem item : sessionItem) {
if (item.getItemId().equals(foodTruckItem.getItemId())) {
// holder.itemTag.setText("MY FAVOURITE");
holder.itemTag.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_favorite));
}
}
}
holder.itemName.setText(foodTruckItem.getItemName());
// holder.itemTag.setText(foodTruckItem.getSpecialTag());
holder.foodPrice.setText("$" + String.valueOf(foodTruckItem.getItemPrice()));
Picasso.Builder builder = new Picasso.Builder(mContext);
builder.listener(new Picasso.Listener() {
@Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
exception.printStackTrace();
}
});
if (!TextUtils.isEmpty(foodTruckItem.getItemImg())) {
builder.build().load(foodTruckItem.getItemImg()).into(holder.itemImage);
}
holder.addText.setOnClickListener(new View.OnClickListener() {
FoodtruckInfo info = new FoodtruckInfo();
@Override
public void onClick(View v) {
for (int l = 0; l < foodtruckInfoList.size(); l++) {
if (foodtruckInfoList.get(l).getItemId().equals(foodTruckItem.getItemId())) {
if (foodtruckInfoList.get(l).getOrderStatus() == 0) {
isClickable = true;
} else {
isClickable = false;
}
}
}
if (isClickable) {
String foodTruckId = null;
if (MyCart.getInstance().getFoodTruckId() != null) {
foodTruckId = MyCart.getInstance().getFoodTruckId();
if (!foodTruckId.equals(foodtruckInfoList.get(position).getFoodTruckId())) {
listener.showWarningDialog(position);
} else {
addItem(holder, position, foodTruckItem);
}
} else {
isConflictResolved = false;
addItem(holder, position, foodTruckItem);
}
} else {
listener.showRestaurentClosed();
}
if (isConflictResolved) {
isConflictResolved = false;
addItem(holder, position, foodTruckItem);
}
}
});
holder.addQuantity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int quantity = foodTruckItem.getItemQuantityOrdered();
quantity += 1;
holder.quantityText.setText(String.valueOf(quantity));
MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
}
});
holder.removeQuantity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int quantity = foodTruckItem.getItemQuantityOrdered();
quantity -= 1;
if (quantity == 0) {
MyCart.getInstance().removeItem(foodTruckItem.getItemId(), false);
holder.addLayout.setVisibility(View.INVISIBLE);
holder.addText.setVisibility(View.VISIBLE);
listener.showSnackBar(quantity, false, position);
} else {
holder.quantityText.setText(String.valueOf(quantity));
MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
}
}
});
setFontStyle(holder);
}
private void addItem(MyViewHolder holder, int position, FoodTruckItem foodTruckItem) {
holder.addLayout.setVisibility(View.VISIBLE);
holder.addText.setVisibility(View.INVISIBLE);
foodTruckItem.setItemQuantityOrdered(1);
holder.quantityText.setText(String.valueOf(1));
MyCart.getInstance().addItem(foodTruckItem);
MyCart.getInstance().setFoodTruckId(foodtruckInfoList.get(position).getFoodTruckId());
listener.showSnackBar(MyCart.getInstance().getItemList(), true, position);
}
private void setFontStyle(MyViewHolder holder) {
holder.itemName.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
// holder.itemTag.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
holder.foodPrice.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
holder.addText.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
}
@Override
public int getItemCount() {
return foodTruckItemList.size();
}
}
Here addConflictItem()
I have written notifyItemChanged
, but somehow it is not calling onBindViewHolder
, so is there anything missing in the application?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With