Reputation: 420
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
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
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