i’ve built a chat application.
inside my chat messages Activity, i have a ListView which shows all text message.
inside each text messages i have a TextView which will by default write "Sending..." and i want it to be updated after the message is sent.
inside each ChatMessage object i have a sent and time property. if sent is true i will show in the TextView the time, and if it’s false i will write "Sending" as written above.
when i’m sending a new message, i’m adding a new view to the ListView adapter, and from some reason it shows that message was sent although it didn’t… can’t really understand why.
this is my ArrayAdapter’s getView() and holder class:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ChatMessage chatMessage = chatMessagesArrayList.get(position);
ChatMessageHolder chatMessageHolder = null;
if (row == null)
{
if (chatMessage.getSenderId() == app.getFacebookCurrentUser().getId())
row = LayoutInflater.from(context).inflate(layoutResourceId, null);
else
row = LayoutInflater.from(context).inflate(R.layout.chat_green, null);
chatMessageHolder = new ChatMessageHolder();
chatMessageHolder.message = (TextView) row.findViewById(R.activity_chat.message);
chatMessageHolder.sentTime = (TextView) row.findViewById(R.activity_chat.sent_time);
chatMessageHolder.isSent = chatMessage.isSent();
row.setTag(chatMessageHolder);
}
else
{
chatMessageHolder = (ChatMessageHolder) row.getTag();
}
chatMessageHolder.message.setText(chatMessage.getMessage());
if (chatMessageHolder.isSent)
chatMessageHolder.sentTime.setText(app.getDateTime(chatMessage.getTime()));
return row;
}
private static class ChatMessageHolder
{
TextView message, sentTime;
boolean isSent = false;
}
i can’t really understand why doesn’t it write the time or “Sending…” according to the isSent boolean flag…
It’s because the ListView recycles previous views (that’s what the
convertViewvariable is). Likely it’s recycling another view that was already set to “Sent”, and you’re never handling the alternate case wherechatMessagerHolder.isSentis false. You should avoid settingchatMessageHolder.isSent = chatMessage.isSent();until after that first if-else block. That first if-else should just be to initialize the view or recycle the object. Also, when you checkif(chatMessageHolder.isSent)you should also handle what theTextViewshould say if that is false (i.e. in a followup else statement) since the views are recycled.