Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scrolling RecyclerView changes other data as well

I am using RecyclerView to show the list of items. I have two TextViews one below other. Initially the second TextView is set to singleline = true.Now on item click, I am setting singleline = false. This is just done to expand it on click (Like ExpandableList). The code works fine but the problem is that as RecyclerView uses the recycled item other items TextView values are also being set to singleline = false. Now how can I avoid this?

Code

public class InboxAdapter extends RecyclerView.Adapter<InboxAdapter.InboxViewHolder> {

    private Context context;
    private List<InboxModel> listInbox;
    private InboxModel currentItem;

    public InboxAdapter(Context context, List<InboxModel> listInbox) {
        this.context = context;
        this.listInbox = listInbox;
    }

    @Override
    public InboxViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.custom_inbox_item, parent, false);
        InboxViewHolder viewHolder = new InboxViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final InboxViewHolder holder, int position) {

        currentItem = listInbox.get(position);
        holder.tvHeader.setText(currentItem.header);
        holder.tvMsg.setText(currentItem.msg);

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

                holder.tvMsg.setSingleLine(false);
                LinearLayout.LayoutParams lp= (LinearLayout.LayoutParams) holder.tvMsg.getLayoutParams();
                lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                holder.tvMsg.setLayoutParams(lp);

            }
        });

    }

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

    class InboxViewHolder extends RecyclerView.ViewHolder {

        private TextView tvImageHeader;
        private TextView tvHeader;
        private TextView tvMsg;
        private TextView tvDate;


        public InboxViewHolder(View itemView) {
            super(itemView);

            tvImageHeader = (TextView) itemView.findViewById(R.id.tv_img_header);
            tvHeader = (TextView) itemView.findViewById(R.id.tv_header);
            tvMsg = (TextView) itemView.findViewById(R.id.tv_msg);
            tvDate = (TextView) itemView.findViewById(R.id.tv_date);
        }
    }
like image 942
Sonali Pawar Avatar asked Nov 25 '25 14:11

Sonali Pawar


2 Answers

You have to set the attribute in all cases to avoid issues with the recycled items.

    @Override
    public void onBindViewHolder(final InboxViewHolder holder, int position){

   //....

   if (currentItem.myBoolean){
      holder.tvMsg.setSingleLine(true);
   } else {
      holder.tvMsg.setSingleLine(false);
   }

   //...
}

In your click event just change the value inside the object (not the view!). Somenthing like:

holder.tvHeader.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    currentItem.myBoolean = true;
                    //call the notify !  
                }
            });

If this state is exclusive, instead of using a variable inside the item use a variable (InboxModel checkedItem) inside the Adapter.

like image 57
Gabriele Mariotti Avatar answered Nov 27 '25 03:11

Gabriele Mariotti


Hmmm For that you have to saved click postion and write condition in onBindViewHolder() like below

@Override
        public void onBindViewHolder(final InboxViewHolder holder, int position) {
    if(Postion==Mysavedposition){
      holder.tvMsg.setSingleLine(false);
    }else{
      holder.tvMsg.setSingleLine(true);
    }
            currentItem = listInbox.get(position);
            holder.tvHeader.setText(currentItem.header);
            holder.tvMsg.setText(currentItem.msg);

            holder.tvHeader.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    Mysavedposition=position;
                    holder.tvMsg.setSingleLine(false);
                    LinearLayout.LayoutParams lp= (LinearLayout.LayoutParams) holder.tvMsg.getLayoutParams();
                    lp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                    holder.tvMsg.setLayoutParams(lp);

                }
            });

        }
like image 29
Pankaj Darji Avatar answered Nov 27 '25 03:11

Pankaj Darji



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!