点击RecyclerView中的项目

时间:2017-12-16 22:36:03

标签: android android-recyclerview onclicklistener android-viewholder

我正在目睹RecyclerView的奇怪行为。所以我在ViewHolder上的Button设置了一个OnClickListener,当用户点击时,它会做3件事:

  1. 将当前项目的数据添加到ArrayList [显示在其他Fragment]上

  2. 向用户显示Toast

  3. 修改所选项目的UI。 [即按钮的View.INVISIBLE等的setVisibility ..]
  4. 现在,虽然OnClickListener的前两个任务已成功完成,并且仅将 应用于所选项目,但第三个任务是修改的用户界面仅选择项,而是也应用于RecyclerView上的每个第9项。

    1. 如何防止此行为?
    2. 为什么仅在第3个任务中发生此行为?
    3. 以前的答案。我看到的特定主题,我认为最好在OnClickListener中插入ViewHolder,而不是将其放入onBindViewHolder,但这并没有解决问题。我已经关注了stackOverflow上的其他建议,但都失败了。

      这是我的代码:

      static class ItemsRecyclerAdapter extends RecyclerView.Adapter<ItemsRecyclerAdapter.ItemsViewHolder>{
      
          FragmentActivity fragmentActivity;
          List<ProductItem> data;
          LayoutInflater inflater;
          private int id;
          private int shopCode;
      
          public ItemsRecyclerAdapter(List<ProductItem> data, FragmentActivity fragmentActivity, int id, int shopCode) {
              this.fragmentActivity = fragmentActivity;
              this.data = data;
              this.inflater = LayoutInflater.from(fragmentActivity);
              this.id = id;
              this.shopCode = shopCode;
          }
      
          @Override
          public ItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
              View v = inflater.inflate(R.layout.pricing_item, parent, false);
      
              return new ItemsViewHolder(v);
          }
      
          @Override
          public void onBindViewHolder(final ItemsViewHolder holder, int position) {
              ProductItem itemPrice = data.get(position);
              holder.productName.setText(itemPrice.getProductName());
              holder.quantity.setText(itemPrice.getProductQuantity());
              holder.tvPrice.setText(itemPrice.getproductPrice());
              Picasso.with(fragmentActivity).load(itemPrice.getThumbUrl()).into(holder.imgProduct);
      
          }
      
          @Override
          public int getItemCount() {
              return data.size();
          }
      
      
              class ItemsViewHolder extends RecyclerView.ViewHolder{
      
              TextView productName, quantity, tvPrice;
              ImageView imgProduct;
              Button btnAddToBasket, btnAdd, btnRemove;
      
              Typeface myCustomFont = Typeface.createFromAsset(fragmentActivity.getAssets(), "fonts/Assistant-SemiBold.ttf");
      
              public ItemsViewHolder(View itemView) {
                  super(itemView);
                  productName = (TextView) itemView.findViewById(R.id.productName);
                  quantity = (TextView) itemView.findViewById(R.id.manufacturer);
                  tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
                  imgProduct = (ImageView) itemView.findViewById(R.id.imgProduct);
                  btnAddToBasket = (Button) itemView.findViewById(R.id.btnAddToBasket);
                  btnAdd = itemView.findViewById(R.id.btnAdd);
                  btnRemove = itemView.findViewById(R.id.btnRemove);
      
                  btnAdd.setVisibility(View.INVISIBLE);
                  btnRemove.setVisibility(View.INVISIBLE);
      
                  quantity.setTypeface(myCustomFont);
                  productName.setTypeface(myCustomFont);
                  tvPrice.setTypeface(myCustomFont);
      
                  Typeface fontAwesomeBasketIcon = Typeface.createFromAsset(fragmentActivity.getAssets(), "fontawesome-webfont.ttf");
                  btnAddToBasket.setTypeface(fontAwesomeBasketIcon);
                  btnAdd.setTypeface(fontAwesomeBasketIcon);
                  btnRemove.setTypeface(fontAwesomeBasketIcon);
      
      
      
                  btnAddToBasket.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                          int pos = getAdapterPosition();
      
                          MyBasketFragment.myBasketList
                                  .add(new ProductItem(data.get(pos).getProductName(), data.get(pos).getProductQuantity(),
                                          data.get(pos).getproductPrice(), data.get(pos).getThumbUrl(), id, shopCode));
      
                          btnAddToBasket.setOnClickListener(null);
      
      
                          Toast.makeText(fragmentActivity, "New product..", Toast.LENGTH_SHORT).show();
      
      
      
                          btnAdd.setVisibility(View.VISIBLE);
                          btnRemove.setVisibility(View.VISIBLE);
      
      
                      }
                  });
      
                  btnAdd.setOnClickListener(new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          ItemsFragment.atomic.incrementAndGet();
                          btnAddToBasket.setText(String.valueOf(atomic.get()));
                      }
                  });
              }
          }
      
        }
      

2 个答案:

答案 0 :(得分:2)

在项目的每次单击时,我将实例化对象中的布尔值指定为true,然后运行notifyDataSetChanged()。使用boolean为真的数据对象更新所有项目。这样我就可以确保所选对象将被更新。

它看起来像这样:

ViewHolder

    class ItemsViewHolder extends RecyclerView.ViewHolder {

        TextView productName, quantity, tvPrice;
        ImageView imgProduct;
        Button btnAddToBasket, btnAdd, btnRemove;

        Typeface myCustomFont = Typeface.createFromAsset(fragmentActivity.getAssets(), "fonts/Assistant-SemiBold.ttf");

        public ItemsViewHolder(View itemView) {
            super(itemView);
            productName = (TextView) itemView.findViewById(R.id.productName);
            quantity = (TextView) itemView.findViewById(R.id.manufacturer);
            tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
            imgProduct = (ImageView) itemView.findViewById(R.id.imgProduct);
            btnAddToBasket = (Button) itemView.findViewById(R.id.btnAddToBasket);
            btnAdd = itemView.findViewById(R.id.btnAdd);
            btnRemove = itemView.findViewById(R.id.btnRemove);

            btnAdd.setVisibility(View.INVISIBLE);
            btnRemove.setVisibility(View.INVISIBLE);

            quantity.setTypeface(myCustomFont);
            productName.setTypeface(myCustomFont);
            tvPrice.setTypeface(myCustomFont);

            Typeface fontAwesomeBasketIcon = Typeface.createFromAsset(fragmentActivity.getAssets(), "fontawesome-webfont.ttf");
            btnAddToBasket.setTypeface(fontAwesomeBasketIcon);
            btnAdd.setTypeface(fontAwesomeBasketIcon);
            btnRemove.setTypeface(fontAwesomeBasketIcon);


        }

        public void bind(final ProductItem item) {
            btnAddToBasket.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    item.clicked = true;
                    item.atomic.incrementAndGet();

                    Toast.makeText(fragmentActivity, "New product..", Toast.LENGTH_SHORT).show();

                    notifyDataSetChanged();

                    MyBasketFragment.myBasketList
                            .add(new ProductItem(item.getProductName(), item.getProductQuantity(),
                                    item.getproductPrice(), item.getThumbUrl(), id, shopCode));
                }
            });

            btnAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ItemsFragment.atomic.incrementAndGet();
                    btnAddToBasket.setText(String.valueOf(atomic.get()));
                }
            });
        }
    }

<强> onBindViewHolder

 @Override
    public void onBindViewHolder(final ItemsViewHolder holder, final int position) {
        ProductItem itemPrice = data.get(position);
        holder.productName.setText(itemPrice.getProductName());
        holder.quantity.setText(itemPrice.getProductQuantity());
        holder.tvPrice.setText(itemPrice.getproductPrice());
        Picasso.with(fragmentActivity).load(itemPrice.getThumbUrl()).into(holder.imgProduct);

        holder.bind(itemPrice);

        if(itemPrice.clicked){
            holder.btnAddToBasket.setOnClickListener(null);

            holder.btnAddToBasket.setText(String.valueOf(atomic.get()));
            holder.btnAdd.setVisibility(View.VISIBLE);
            holder.btnRemove.setVisibility(View.VISIBLE);

        } else {
            holder.btnAddToBasket.setText("\uf291");
            holder.btnAdd.setVisibility(View.INVISIBLE);
            holder.btnRemove.setVisibility(View.INVISIBLE);
        }
    }

答案 1 :(得分:0)

我认为getAdapterPosition()导致问题。请尝试在视图中创建新的int属性positiononBindViewHolder将位置传递给视图所有者holder.position = position,并在视图中使用该位置,因此将{{1}而不是int pos = position