1

I have a custom adapter that displays the messages in conversation. Now I want to bold the textview if the message is not read and otherwise unbold it. However when I scroll the listview of that adapter, the TextViews do not keep the previous setup, they lose the bolded text or bold the read text. I have tried many solutions on SO, however nothing has worked so far.

I have put all the variables into a holder class:

private class Holder {
    public TextView messageTo, messageContent, date;
    public ImageView imgView;
    public Typeface face, bold;
    public int boldText, normalText;
    public int readState;
}

and in getView I get the message item at the position and retrieve the readState from there (some redundant parts have been omitted)

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View convertView1 = convertView;
    LayoutInflater vi = (LayoutInflater) ctx
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    Message message = getItem(position);
    if (convertView1 == null) {
        holder = new Holder();
        convertView1 = vi.inflate(R.layout.list_view_main, parent,
                false);
        holder.messageTo = (TextView) convertView1
                .findViewById(R.id.address);
        holder.messageContent = (TextView) convertView1
                .findViewById(R.id.previewMsg);
        holder.date = (TextView) convertView1.findViewById(R.id.showDate);
        holder.imgView = (ImageView) convertView1
                .findViewById(R.id.quickBadge);
        holder.face = Typeface.createFromAsset(ctx.getAssets(),
                "fonts/helveticaneuelight.ttf");
        holder.bold = Typeface.createFromAsset(ctx.getAssets(),
                "fonts/helveticaneue.ttf");
        holder.boldText = Typeface.BOLD;
        holder.normalText = Typeface.NORMAL;
        holder.readState = getItem(position).readState;
        convertView1.setTag(holder);
    } else {
        holder = (Holder) convertView1.getTag();
    }

    if(holder.readState==0) {
        holder.messageTo.setText(message.messageNumber);
        holder.messageContent.setText(message.messageContent);
        holder.date.setText(message.messageDate);
        holder.messageTo.setTypeface(holder.bold, holder.boldText);
        holder.messageContent.setTypeface(holder.face, holder.boldText);
        holder.date.setTypeface(holder.face, holder.boldText);
    } else {
        holder.messageTo.setText(message.messageNumber);
        holder.messageContent.setText(message.messageContent);
        holder.date.setText(message.messageDate);
        holder.messageTo.setTypeface(holder.bold, holder.normalText);
        holder.messageContent.setTypeface(holder.face, holder.normalText);
        holder.date.setTypeface(holder.face, holder.normalText);
    }
    return convertView1;
}

But it does not work. Anyone has a solution for this?

Kise
  • 2,823
  • 1
  • 24
  • 43
  • 1
    can u try not putting read state in the holder class? – Shaz Mar 19 '15 at 04:28
  • you can use `if(message.readState==0) { // do smething. set font}else{//do something. set font}` and remove `holder.readState = getItem(position).readState;` – Raghunandan Mar 19 '15 at 04:34
  • @Shaz strangely enough, that's what I initially did but now it is working perfectly! You might want to repost the answer and I will mark it as correct. – Kise Mar 19 '15 at 04:38
  • @BlameTheBrain ok i will post it as an answer – Raghunandan Mar 19 '15 at 04:39
  • @Raghunandan thank you, I did it at the beginning but it seems that the issues was in another method so I did not get the desired result at that moment. Now it works as expected. – Kise Mar 19 '15 at 04:40
  • @BlameTheBrain check the link in the post it should help you understand how listview recycling works – Raghunandan Mar 19 '15 at 04:43

2 Answers2

1

Try this

if(message.readState==0) {
    // keep your other part of the code as it is
    // set font
} else {
   // keep your other code as it is
    // set font
}

You can get rid of

 holder.readState = getItem(position).readState;

To understand how it works

How ListView's recycling mechanism works

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
1

you can follow Raghunandan's answer but below answer also helps you:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View convertView1 = convertView;
    LayoutInflater vi = (LayoutInflater) ctx
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    Message message = getItem(position);
    final Holder holder;
    if (convertView1 == null) {
        holder = new Holder();
        convertView1 = vi.inflate(R.layout.list_view_main, parent,
                false);
        holder.messageTo = (TextView) convertView1
                .findViewById(R.id.address);
        holder.messageContent = (TextView) convertView1
                .findViewById(R.id.previewMsg);
        holder.date = (TextView) convertView1.findViewById(R.id.showDate);
        holder.imgView = (ImageView) convertView1
                .findViewById(R.id.quickBadge);
        holder.face = Typeface.createFromAsset(ctx.getAssets(),
                "fonts/helveticaneuelight.ttf");
        holder.bold = Typeface.createFromAsset(ctx.getAssets(),
                "fonts/helveticaneue.ttf");
        holder.boldText = Typeface.BOLD;
        holder.normalText = Typeface.NORMAL;
        holder.readState = getItem(position).readState;
        convertView1.setTag(holder);
    } else {
        holder = (Holder) convertView1.getTag();
    }

    if(holder.readState==0) {
        holder.messageTo.setText(message.messageNumber);
        holder.messageContent.setText(message.messageContent);
        holder.date.setText(message.messageDate);
        holder.messageTo.setTypeface(holder.bold, holder.boldText);
        holder.messageContent.setTypeface(holder.face, holder.boldText);
        holder.date.setTypeface(holder.face, holder.boldText);
    } else {
        holder.messageTo.setText(message.messageNumber);
        holder.messageContent.setText(message.messageContent);
        holder.date.setText(message.messageDate);
        holder.messageTo.setTypeface(holder.bold, holder.normalText);
        holder.messageContent.setTypeface(holder.face, holder.normalText);
        holder.date.setTypeface(holder.face, holder.normalText);
    }
    return convertView1;
}

just create holder object inside getview() method.

Sagar Maiyad
  • 12,655
  • 9
  • 63
  • 99