Sonali Pawar
Sonali Pawar

Reputation: 420

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

Upvotes: 3

Views: 2265

Answers (2)

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363479

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.

Upvotes: 2

Pankaj Darji
Pankaj Darji

Reputation: 146

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

                }
            });

        }

Upvotes: 1

Related Questions