点击RecyclerView中的项目

问题描述 投票:0回答:2

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

  1. 将当前项目的数据添加到ArrayList [显示在不同的Fragment]
  2. 向用户显示Toast
  3. 修改所选项目的UI。 [即按钮对View.INVISIBLE等的可见性..]

现在,虽然OnClickListener的前两个任务已成功完成并且仅适用于所选项目,但第三个任务仅用于修改所选项目的UI,而是也应用于RecyclerView上的每个第9个项目。

  1. 我该如何防止这种行为?
  2. 为什么仅在第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()));
                }
            });
        }
    }

  }
android android-recyclerview onclicklistener android-viewholder
2个回答
2
投票

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

它看起来像这样:

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);
        }
    }

0
投票

我认为getAdapterPosition()造成了这个问题。请尝试在视图中创建一个新的int属性positiononBindViewHolder将该位置传递给viewholder,holder.position = position,并在你的viewholder中使用该位置,因此将是int pos = position而不是getAdapterPosition()

© www.soinside.com 2019 - 2024. All rights reserved.