3

My goal is to programmatically change the text size of a Textview item within certain Cardviews, which are contained in a recyclerview. I am successfully able to do that, with an unusual side effect. What happens then is that, although the correct cardviews' textview's properties have been successfully modified, random cards, which are not suppose to be modified, are now modified. However, as the user scrolls through more and more of the recyclerview, both directions, the more and more cards are modified. Eventually, what began with a few random cards (in addition to my request cards) lead to all the calls being modified.

A better example: Let's say I have 5 cards I want to change the text size to something else, within a recyclerview containing 50 cards. Now, those cards, along with a few other, random cards, are now have big text. The rest remain small. As the user scrolls up and down, more and more cards are being set to have big text, until all cards have big text.

How my code works is that I have a class, ListAdapter which extends RecyclerView.Adapter<ListAdapter.VersionViewHolder>. Since I gather my objects from a database, I use arraylists to gather my info, and programmically add them in, as shown:

@Override
public void onBindViewHolder(VersionViewHolder versionViewHolder, int i) {
    if (ActivitiesList.size() != 0)
        versionViewHolder.title.setText(ActivitiesList.get(i));
    if (ActivitiesSubList.size() != 0)
        versionViewHolder.subTitle.setText(ActivitiesSubList.get(i));
    if (ActivitiesSubList2.size() != 0)
        versionViewHolder.subTitle2.setText(ActivitiesSubList2.get(i));
    if (ActivitiesID.size() != 0)
        versionViewHolder.id.setText(ActivitiesID.get(i));

    // TODO: POST QUESTION ON STACK OVERFLOW
    if (!ActivitiesTag.get(i).equals("")) {
        Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
        versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
    }

}

I set ActivitiesList,ActivitiesSubList,ActivitiesSubList2,ActivitiesID, and ActivitiesTag within a child class GradesListAdapter which extends the ListAdapter.

What should be noted is the ActivitiesTag Arraylist. When I wish to add an value to be large, I simply insert any non-empty value into the arraylist. Otherwise, I add an empty string. Thus, for it to be large, it must successfully fulfill the criteria. (On a side note, is there any way of improving this method?) On testing, it appears that only the cards with the correct position are set to be large, but nevertheless it also affects non-tagged cards.

Here is the VersionViewHolder class:

class VersionViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    CardView cardItemLayout;
    TextView title;
    TextView subTitle;
    TextView subTitle2;
    TextView id;

    public VersionViewHolder(View itemView) {
        super(itemView);
        cardItemLayout = (CardView) itemView.findViewById(R.id.grades_item);
        title = (TextView) itemView.findViewById(R.id.listitem_name);
        subTitle = (TextView) itemView.findViewById(R.id.listitem_subname);
        subTitle2 = (TextView) itemView.findViewById(R.id.listitem_subname2);
        id = (TextView) itemView.findViewById(R.id.listitem_id);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        clickListener.onItemClick(v, getAdapterPosition());
    }
}

What can I do to remove this unintended side effect? I believe I have all the data needed for others to help debug this, but if I'm missing something, please say so; I'm still quite new to StackOverflow.

Thank you for reading.

xes_p
  • 501
  • 4
  • 14

1 Answers1

4

In your onbindViewHolder, change

if (!ActivitiesTag.get(i).equals("")) {
    Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
    versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
}

to

if (!ActivitiesTag.get(i).equals("")) {
    Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
    versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
}else{
    versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP,"Your Original Text Size");
}

If you only set an if clause without an else clause in viewholder, since this view is reused again and again, your text size will not be reset to normal. So, you'll have to manually reset the text size.

Ye Myat Thu
  • 197
  • 7
  • That's an amazingly simple answer. I'm embarrassed I didn't see that. Thank you so much. Do you know specifically why it affects other cards though? – xes_p Jul 17 '15 at 04:58
  • 1
    Please look at this SO answer for more information about viewholder and recycling http://stackoverflow.com/questions/11945563/how-listviews-recycling-mechanism-works – Ye Myat Thu Jul 17 '15 at 05:08