Hello to all programmers. I try to create simple chat. The first chatter's messages should be in white square with rounded corners, the second chatter's messages should be in blue square with rounded corners and with some icon. So I decided to use listview and adapter for this task. In adapter I use simple set of data {bool type, sting message, DateTime date}. So Adapter Code is
class ChatMessagesViewHolder : Java.Lang.Object
{
internal TextView chatMessageView;
public void initialize(View view){}
}
public class ChatMessagesAdapter : BaseAdapter
{
Activity _context;
List<MessageData> _dataList;
public ChatMessagesAdapter(Activity context, List<MessageData> dataList)
{
_context = context;
_dataList = dataList;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
ChatMessagesViewHolder chatMessagesViewHolderClass;
View view;
view = convertView;
int layout = _dataList[position]._type == 0 ? Resource.Layout.MessageLitsUserItem:Resource.Layout.MessageListWorkerItem;
Typeface openSansRegular = Typeface.CreateFromAsset(_context.Assets, "fonts/OpenSans-Regular.ttf");
if (view == null)
{
view = _context.LayoutInflater.Inflate(layout, parent, false);
chatMessagesViewHolderClass = new ChatMessagesViewHolder();
chatMessagesViewHolderClass.chatMessageView = view.FindViewById<TextView>(Resource.Id.messageText);
chatMessagesViewHolderClass.initialize(view);
view.Tag = chatMessagesViewHolderClass;
}
else
{
chatMessagesViewHolderClass = (ChatMessagesViewHolder)view.Tag;
}
chatMessagesViewHolderClass.chatMessageView.Typeface = openSansRegular;
chatMessagesViewHolderClass.chatMessageView.Text = _dataList[position]._date.ToString()+"\n"+ _dataList[position]._message;
return view;
}
public void Add(MessageData messageData)
{
_dataList.Add(messageData);
}
}
In Activity I fill Adapter with test information that way - message from 1-st chatter, message from 2-nd chatter. It repeats 10 times.
public class ChatActivity : Activity{
ListView chatList;
ChatMessagesAdapter chatAdapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ChatLayout);
List<MessageData> dataList = new List<MessageData>();
for (int i = 0; i < 20; i++)
{
string message = "Test message from chatter "+(i%2).ToString();
dataList.Add(new MessageData(i % 2, message, DateTime.Now));
}
chatAdapter = new ChatMessagesAdapter(this, dataList);
chatList.Adapter = chatAdapter;
}
}
When I run app (in Visual studio emulator for android) first rendering of list is correct, but when I scroll list up/down, the layouts of ListView mixes - 1-st chatter's message sometimes get 2-nd chatter's template (with blue square and icon), 2-nd chatter's message sometimes get 1-st chatter's template (with white square and no icon). For Example
Can anybody help me with this issue? Any help will be appreciated.
UPDATED
New code of Adapter, updated to work with two different ViewHolders for different type of messages.
class ChatUserMessagesViewHolder : Java.Lang.Object
{
internal RelativeLayout messageBox;
internal TextView messageText;
public void initialize(View view) { }
}
class ChatWorkerMessagesViewHolder : Java.Lang.Object
{
internal RelativeLayout messageBox;
internal TextView messageText;
internal ImageView workerIcon;
public void initialize(View view) { }
}
public class ChatMessagesAdapter : BaseAdapter
{
Activity _context;
List<MessageData> _dataList;
public ChatMessagesAdapter(Activity context, List<MessageData> dataList)
{
_context = context;
_dataList = dataList;
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
public override long GetItemId(int position)
{
return position;
}
public override int Count
{
get
{
return _dataList.Count;
}
}
public override int GetItemViewType(int position)
{
return _dataList[position]._type;
}
public override int ViewTypeCount
{
get
{
return 2;
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
ChatMessagesViewHolder chatMessagesViewHolderClass;
ChatWorkerMessagesViewHolder chatWorkerMessagesViewHolderClass;
ChatUserMessagesViewHolder chatUserMessagesViewHolderClass;
View view;
view = convertView;
int layout = _dataList[position]._type == 0 ? Resource.Layout.MessageLitsUserItem:Resource.Layout.MessageListWorkerItem;
Typeface openSansRegular = Typeface.CreateFromAsset(_context.Assets, "fonts/OpenSans-Regular.ttf");
if (view == null)
{
switch (GetItemViewType(position))
{
case 0:
view = _context.LayoutInflater.Inflate(Resource.Layout.MessageLitsUserItem, null);
chatUserMessagesViewHolderClass = new ChatUserMessagesViewHolder();
chatUserMessagesViewHolderClass.messageBox = view.FindViewById<RelativeLayout>(Resource.Id.messageBox);
chatUserMessagesViewHolderClass.messageText = view.FindViewById<TextView>(Resource.Id.messageText);
chatUserMessagesViewHolderClass.messageText.Typeface = openSansRegular;
chatUserMessagesViewHolderClass.messageText.Text = _dataList[position]._date.ToString() + "\n" + _dataList[position]._message;
view.Tag = chatUserMessagesViewHolderClass;
break;
case 1:
view = _context.LayoutInflater.Inflate(Resource.Layout.MessageListWorkerItem, null);
chatWorkerMessagesViewHolderClass = new ChatWorkerMessagesViewHolder();
chatWorkerMessagesViewHolderClass.messageBox = view.FindViewById<RelativeLayout>(Resource.Id.messageBox);
chatWorkerMessagesViewHolderClass.messageText = view.FindViewById<TextView>(Resource.Id.messageText);
chatWorkerMessagesViewHolderClass.workerIcon = view.FindViewById<ImageView>(Resource.Id.workerIcon);
chatWorkerMessagesViewHolderClass.messageText.Typeface = openSansRegular;
chatWorkerMessagesViewHolderClass.messageText.Text = _dataList[position]._date.ToString() + "\n" + _dataList[position]._message;
break;
}
}
else
{
switch (GetItemViewType(position))
{
case 0:
chatUserMessagesViewHolderClass = (ChatUserMessagesViewHolder)view.Tag;
chatUserMessagesViewHolderClass.messageText.Typeface = openSansRegular;
chatUserMessagesViewHolderClass.messageText.Text = _dataList[position]._date.ToString() + "\n" + _dataList[position]._message;
break;
case 1:
chatWorkerMessagesViewHolderClass = (ChatWorkerMessagesViewHolder)view.Tag;
chatWorkerMessagesViewHolderClass.messageText.Typeface = openSansRegular;
chatWorkerMessagesViewHolderClass.messageText.Text = _dataList[position]._date.ToString() + "\n" + _dataList[position]._message;
break;
}
}
return view;
}
public void Add(MessageData messageData)
{
_dataList.Add(messageData);
}
}