user8356857
user8356857

Reputation:

Button click on recycler view is repeating

I have a RecyclerView. Data comes from a server. A list item view contains:

I have 10 list items. When I click the button data will send to the server, and after successful submission the button visibility is set to View.INVISIBLE. The problem is that every 7th button is also changed to invisible. The data transfer is working properly. Please help me.

Bind the view holder

@Override
public void onBindViewHolder(final ViewHolder1 holder, final int position) {
    final Ardlist_item listitem = listitems.get(position);

    holder.textitemname.setText(listitem.getItemname());
    holder.liftqty.setText(listitem.getQty());

    holder.rcqty.setText(listitem.getQty());

    holder.b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            holder.b1.setVisibility(View.INVISIBLE);
            holder.rcqty.setEnabled(false);
            Toast.makeText(context, "clicled" + position, Toast.LENGTH_LONG).show();

        }
    });
}

Getting the position

@Override
public int getItemCount() {
    return listitems.size();
}

public class ViewHolder1 extends RecyclerView.ViewHolder {

    public TextView liftqty;

    public Button b1;
    public EditText rcqty;
    public ViewHolder1(View itemView) {

        super(itemView);
        textitemname = (TextView) itemView.findViewById(R.id.item_name);
        liftqty = (TextView) itemView.findViewById(R.id.lifted_qty);

        b1 = (Button) itemView.findViewById(R.id.receive_btn);
        rcqty = (EditText) itemView.findViewById(R.id.received_qty);

    }    
}

Upvotes: 0

Views: 1451

Answers (5)

Daksh Rawal
Daksh Rawal

Reputation: 420

even I was facing the same issue , there are 2 ways to solve this problem ;

  1. {your recycler view}.setItemViewCacheSize(9); I found 9 to work perfectly with my code and probably should work with even yours.

  2. In Your Adapter Class , under onBindViewHolder Add A line " holder.bind(userModal1); "

    then create a method named bind under the ViewHolder

    then set the same textview , imageview , button same as you did in the onBindViewHolder

for a better understanding i have added a photo as well

first method to solve the issue

{

cache one

}

this is the second method

{

onBindViewHolder

ViewHolder---method bind

}

Upvotes: 1

programming me fun
programming me fun

Reputation: 1

I was facing same problem. Hopefully, after a lot of research, I found a solution.

Actually recyclerview creates 8 view holders after then it reuses the already made adaptors. So if you make any change in them it will be continue to every 7th view holder cause both are same.

So to solve it you have to initialise all views of viewholders everytime you use.

Upvotes: 0

Fori
Fori

Reputation: 485

You need update every view inside onBindViewHolder. So add attr "active" to your model and update after click:

@Override
public void onBindViewHolder(final ViewHolder1 holder, final int position) {
    final Ardlist_item listitem = listitems.get(position);

    holder.textitemname.setText(listitem.getItemname());
    holder.liftqty.setText(listitem.getQty());
    holder.rcqty.setText(listitem.getQty());

    holder.b1.setVisibility(listitem.isActive() ? View.VISIBLE : View.INVISIBLE); // set visibility
    holder.rcqty.setEnabled(listitem.isActive());

    holder.b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Ardlist_item listitem = listitems.get(position);
            listitem.setActive(false); // edit active attribute
            holder.b1.setVisibility(View.INVISIBLE);
            holder.rcqty.setEnabled(false);
            Toast.makeText(context, "clicled" + position, Toast.LENGTH_LONG).show();
        }
    });
}

Add attr active:

class Ardlist_item {
        //private boolean active = true;//chnaged
   private boolean active = true;

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}

Upvotes: 1

MeliX
MeliX

Reputation: 240

RecyclerView recycles views that are not visible to the user anymore. That means, that the one you have made INVISIBLE will be invisible when it's recycled. For each item you have to restore the state of the view by setting holder.b1.setVisibility(View.VISIBLE); in onBindViewHolder. However, it will reset those items that are sent to the server side. You have to implement logic to save a state of the items. Let's say listitem.isSent(). Then you will have:

final Ardlist_item listitem = listitems.get(position);

holder.b1.setVisibility(listitem.isSent()? View.INVISIBLE : View.VISIBLE);
holder.textitemname.setText(listitem.getItemname());
...
            holder.b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listitems.setSent(true);

                holder.b1.setVisibility(View.INVISIBLE);
                holder.rcqty.setEnabled(false);
                Toast.makeText(context, "clicled" + position, Toast.LENGTH_LONG).show();

            }
        });

Upvotes: 2

Ashwani
Ashwani

Reputation: 1304

simply add this line holder.b1.setVisibility(View.VISIBLE); after holder.rcqty.setText(listitem.getQty()); it will do. It happens because the view is recycled and on recycling it is found that its visibility is gone which arises the problem that you are facing.

Upvotes: 0

Related Questions