Reputation: 33
I'm having a sectioned recyclerview with title header and items under that catergoty. I have two viewHolders one for the title, and other for the items that come under that category. Here is my Adapter.
public class MenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final String TAG = MenuAdapter.class.getSimpleName();
private Context mContext;
private ItemClickListener itemClickListener;
private List<HeterogeneousObject> heterogeneousObjects;
public MenuAdapter(Context mContext, CartHelper helper) {
this.mContext = mContext;
heterogeneousObjects = new ArrayList<>();
}
public void itemClickListenerCallback(ItemClickListener itemClickListenerCallback) {
this.itemClickListener = menuItemClickListenerCallback;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 0) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single_cuisine_rv, parent, false);
return new MenuAdapterViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single_cuisine_menu_items, parent, false);
return new RecycledGridViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
HeterogeneousObject object = heterogeneousObjects.get(position);
if (object.getItemType() == 0) {
if (object.getCuisine() != null) {
MenuAdapterViewHolder holder = (MenuAdapterViewHolder) viewHolder;
holder.cuisineName.setText(object.getCuisine().getCuisine_name());
}
} else {
if (object.getMenuItem() != null) {
RecycledGridViewHolder holder = (RecycledGridViewHolder) viewHolder;
holder.dishName.setText(object.getMenuItem().getItemName());
holder.dishPrice.setText(mContext.getString(R.string.rupee_symbol, object.getMenuItem().getItemPrice() * 0.01));
if (object.getMenuItem().getIsVeg()) {
holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.veg_symbol));
//holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_veg_indicator));
} else if (!object.getMenuItem().getIsVeg()) {
holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.non_veg_symbol));
//holder.vegNonVegIndicator.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_non_veg_indicator));
}
Single<CartSelection> selection = cartHelper.getCartSelectionById(Long.parseLong(object.getMenuItem().getItemId()));
selection.subscribe(new DisposableSingleObserver<CartSelection>() {
@Override
public void onSuccess(CartSelection cartSelection) {
if (cartSelection != null) {
holder.incDecButton.setNumber(cartSelection.getQty(), true);
}
}
@Override
public void onError(Throwable e) {
}
});
holder.bind(object.getMenuItem(), menuItemClickListener);
}
}
}
@Override
public int getItemCount() {
return heterogeneousObjects.size();
}
@Override
public int getItemViewType(int position) {
super.getItemViewType(position);
if (heterogeneousObjects.get(position).getItemType() == 0) {
return 0;
} else {
return 1;
}
}
}
Here is my View Holder 1
public class RecycledGridViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv_si_dish_name)
TextView dishName;
@BindView(R.id.tv_si_dish_price)
TextView dishPrice;
@BindView(R.id.btn_id_item_dish_grid)
IncDecButton incDecButton;
@BindView(R.id.iv_veg_non_veg_grid)
AppCompatImageView vegNonVegIndicator;
public RecycledGridViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(final MenuItem menuItem, final MenuItemClickListener menuItemClickListener) {
incDecButton.setOnButtonsClickedListener(new IncDecButton.OnButtonsClickedListener() {
@Override
public void onPlusClicked(int num) {
if (menuItem.getCustomizable()) {
menuItemClickListener.onCustomizableItemClicked(menuItem, 1);
if (incDecButton.getNumber() == 0) {
incDecButton.setNumber(0, true);
}
} else {
menuItemClickListener.onPlusButtonClicked(menuItem, num);
}
}
@Override
public void onMinusClicked(int num) {
if (menuItem.getCustomizable()) {
menuItemClickListener.onCustomizableItemClicked(menuItem, 0);
} else {
menuItemClickListener.onMinusButtonClicked(menuItem, num);
}
}
});
}
View Holder 2
class MenuAdapterViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.tv_cuisine_name_menu_v2)
TextView cuisineName;
public MenuAdapterViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
I'm maintaining a state of item count that the list item in ViewHolder 1 has to show in IncDecButton outside of the ViewHolder in a ROOM Db Dao, which i query as onBindViewHolder is called for each item but the views gets recycled and item count gets misplaced.
when i only have a single view holder, i.e only View Holder 1, item counts have no issues, but it gets recycled and misplaced when there are 2 View Holders. I don't really seem to understand what am i doing wrong.
This code works fine with only a single Viewholder (Single Item Type RecyclerView).
Upvotes: 3
Views: 1571
Reputation: 1315
Views in a RecyclerView
are recycled when dissapear in the screen. You should manage the state outside the ViewHolder
and just use it for the presentation. You could store the current value of the count in the item data you pass to the adapter and then just show this current value in the ViewHolder
.
Another important thing is to set always the value. If you do not put the correct value, the ViewHolder
will maintain the recycled view, so if the count for new cells is 0, just put 0 in the binding.
Hope it helps.
Upvotes: 2