1

I have a Recyclerview that in each item, I put 2 buttons named IncementBtn nad DecrementBtn to increment and decrement item in ListOrders.And a Textview that show the number of the item .The Recyclerview is in viewpager and each page of pager related to ViewPager Tabs. When I click the incrementBtn to add quantity one more, the seventh position also changed And show the quantity number as a clicked item. Everything is good just when I clicked an item the seventh item also affected.

 public class SimpleStringRecyclerViewAdapter : RecyclerView.Adapter
            {
                private readonly TypedValue mTypedValue = new TypedValue();
                private int mBackground;
                private List<Food> mValues;
                Resources mResource;
                private Dictionary<int, int> mCalculatedSizes;

                public SimpleStringRecyclerViewAdapter(Context context, List<Food> items, Resources res)
                {
                    context.Theme.ResolveAttribute(Resource.Attribute.selectableItemBackground, mTypedValue, true);
                    mBackground = mTypedValue.ResourceId;
                    mValues = items;
                    mResource = res;

                    mCalculatedSizes = new Dictionary<int, int>();
                }

                public override int ItemCount
                {
                    get { return mValues.Count; }
                }

                public override async void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
                {
                    var simpleHolder = holder as SimpleViewHolder;

                    //simpleHolder.mBoundString = mValues[position].;
                    simpleHolder.mFoodNameTxt.Text = mValues[position].Name;
                    simpleHolder.mPriceTxt.Text = mValues[position].Price.ToString();
                    simpleHolder.foodId = mValues[position].FoodId;
                    simpleHolder.position = position;

                }

                public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
                {

                    View view = LayoutInflater.From(parent.Context)
                        .Inflate(Resource.Layout.food_list_item, parent, false);
                    view.SetBackgroundResource(mBackground);

                    return new SimpleViewHolder(view);
                }
            }

            public class SimpleViewHolder : RecyclerView.ViewHolder
            {
                public string mBoundString;
                public  View mView;
                public  ImageView mImageView;
                public  TextView mFoodNameTxt;
                public  TextView mPriceTxt;
                public  Button mIncrementBtn;
                public  Button mDcrementBtn;
                public  TextView _quantitiyTxt;
                public int foodId;
                private static int quntitySum = 0;
                public int position;
                public SimpleViewHolder(View view) : base(view)
                {
                    mView = view;


                    //mImageView = view.FindViewById<ImageView>(Resource.Id.avatar);
                    mFoodNameTxt = view.FindViewById<TextView>(Resource.Id.lbl_food_name);
                    mPriceTxt = view.FindViewById<TextView>(Resource.Id.lbl_price);

                    mIncrementBtn = view.FindViewById<Button>(Resource.Id.increment_btn);
                    _quantitiyTxt = view.FindViewById<TextView>(Resource.Id.quantity_txt);

                    mDcrementBtn = view.FindViewById<Button>(Resource.Id.decrement_btn);

                    mDcrementBtn.Click += delegate
                    {

                        //Find order and decrement
                        var orderItem = orderList.Find(p => p.FoodId == foodId);
                        orderItem.Quantity--;
                        _quantitiyTxt.Text = orderItem.Quantity.ToString();
                        _fabCart.SetImageBitmap(ConvertTextToBitmap.TextAsBitmap((--quntitySum).ToString(), 36, Color.White));

                        if (orderItem.Quantity == 0)
                        {
                            mDcrementBtn.Visibility = ViewStates.Invisible;
                            _quantitiyTxt.Visibility = ViewStates.Invisible;
                            _quantitiyTxt.Text = "";
                            orderList.Remove(orderItem);
                        }
                        if (orderList.Count == 0)
                        {
                            _fabCart.Visibility = ViewStates.Gone;
                        }

                    };

                    mIncrementBtn.Click += delegate
                    {

                        _fabCart.Show();
                        mDcrementBtn.Visibility = ViewStates.Visible;
                        _quantitiyTxt.Visibility = ViewStates.Visible;
                        if (orderList.Any(p=>p.FoodId==foodId))
                        {
                            //Find order and increment
                            var orderItem = orderList.Find(p => p.FoodId == foodId);
                            orderItem.Quantity++;
                            _quantitiyTxt.Text = orderItem.Quantity.ToString();

                        }
                        else
                        {

                            orDetail = new Order
                            {
                                FoodId = foodId,
                                FoodName = mFoodNameTxt.Text,
                                Price = Convert.ToInt32(mPriceTxt.Text)
                            };
                            orDetail.Quantity++;
                            orderList.Add(orDetail);
                            _quantitiyTxt.Text = orDetail.Quantity.ToString();

                        }

                        _fabCart.SetImageBitmap(ConvertTextToBitmap.TextAsBitmap((++quntitySum).ToString(), 36, Color.White));

                    };


                }


                public override string ToString()
                {
                    return base.ToString() + " '" + mFoodNameTxt.Text;
                }
            }

What am I wrong? Please help to over Overwhelm this.

I have a funny pic to show the problem. enter image description here

iman mohadesi
  • 109
  • 1
  • 8
  • because it is recyclerView which means recycles views over and over. You can check [this post](https://stackoverflow.com/questions/32427889/checkbox-in-recyclerview-keeps-on-checking-different-items) as a reference – Murat Güç Dec 26 '17 at 14:00
  • CachingStrategy="RecycleView" is recomended for static rows, it just refresh binding values, may be you should show from begining all controls and just refres quantity. – Uraitz Dec 26 '17 at 14:03
  • @MuratGuc Thanks , but it does not make any sense for me – iman mohadesi Dec 26 '17 at 14:45
  • This is most likely a bug in your `ViewHolder` in which the view is being recycled. Check your logic in your `ViewHolder`. In short, make sure you have a "default" setting to the `ViewHolder` first, and then add checks for visibility/etc after. – Jon Douglas Dec 26 '17 at 16:45

2 Answers2

4

Try set ItemCachedSize for recyclerView when you setup your recyclerView.

YourRecyclverView.setAdapter(matchItemAdapter);
YourRecyclverView.setNestedScrollingEnabled(false);
YourRecyclverView.setLayoutManager(layoutManager);
YourRecyclverView.setItemViewCacheSize(100);

I got this bug and solved by set Item cached view to 100.

CloudKlose
  • 61
  • 1
  • 9
1

As @jon-douglas said , I add this code to OnBindViewHolder to fix the bug.

 simpleHolder.mDcrementBtn.Visibility = ViewStates.Invisible;
 simpleHolder._quantitiyTxt.Visibility = ViewStates.Invisible;
 simpleHolder._quantitiyTxt.Text = "";

 var item = orderList.Find(p => p.FoodId == mValues[position].FoodId);
 if (item != null && item.ClickFlag)
 {
   simpleHolder.mDcrementBtn.Visibility = ViewStates.Visible;
   simpleHolder._quantitiyTxt.Visibility = ViewStates.Visible;
   simpleHolder._quantitiyTxt.Text = item.Quantity.ToString();
 }
iman mohadesi
  • 109
  • 1
  • 8