之前一直不知道有getItemViewType这个方法,多View适配一直多判断方法,如下:
ViewHolder viewHolder;
if (convertView == null || convertView.getTag(R.drawable.ic_launcher + come) == null) {
//自己发的
if (come == ChatConstants.OUTGOING) {
convertView = mInflater.inflate(R.layout.chat_item_right, parent, false);
} else {//别人发 的
convertView = mInflater.inflate(R.layout.chat_item_left, null);
}
viewHolder = buildHolder(convertView);
convertView.setTag(R.drawable.ic_launcher + come, viewHolder);
convertView.setTag(R.string.app_name, R.drawable.ic_launcher + come);
} else {
viewHolder = (ViewHolder) convertView.getTag(R.drawable.ic_launcher + come);
}
因为要做聊天,后来了选择了第三方聊天环信。由于要自定义消息类型,所以要修改消息适配器。
环信官方demo就用到了getItemViewType来解决多View适配convertView重用的这个问题。请看下面代码:
由于官方demo代码比较多所以这里就粘贴一部分,如果想全面研究就下载附件吧
private static final int MESSAGE_TYPE_RECV_TXT = 0;
private static final int MESSAGE_TYPE_SENT_TXT = 1;
private static final int MESSAGE_TYPE_SENT_IMAGE = 2;
private static final int MESSAGE_TYPE_SENT_LOCATION = 3;
private static final int MESSAGE_TYPE_RECV_LOCATION = 4;
private static final int MESSAGE_TYPE_RECV_IMAGE = 5;
private static final int MESSAGE_TYPE_SENT_VOICE = 6;
private static final int MESSAGE_TYPE_RECV_VOICE = 7;
private static final int MESSAGE_TYPE_SENT_VIDEO = 8;
private static final int MESSAGE_TYPE_RECV_VIDEO = 9;
private static final int MESSAGE_TYPE_SENT_FILE = 10;
private static final int MESSAGE_TYPE_RECV_FILE = 11;
private static final int MESSAGE_TYPE_SENT_VOICE_CALL = 12;
private static final int MESSAGE_TYPE_RECV_VOICE_CALL = 13;
private static final int MESSAGE_TYPE_SENT_VIDEO_CALL = 14;
private static final int MESSAGE_TYPE_RECV_VIDEO_CALL = 15;
private static final int MESSAGE_TYPE_SENT_ROBOT_MENU = 16;
private static final int MESSAGE_TYPE_RECV_ROBOT_MENU = 17;
/**
* 获取item类型数
*/
public int getViewTypeCount() {
return 18;
}
/**
* 获取item类型
*/
public int getItemViewType(int position) {
EMMessage message = getItem(position);
if (message == null) {
return -1;
}
if (message.getType() == EMMessage.Type.TXT) {
if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false))
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE_CALL : MESSAGE_TYPE_SENT_VOICE_CALL;
else if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false))
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO_CALL : MESSAGE_TYPE_SENT_VIDEO_CALL;
else if(((DemoHXSDKHelper)HXSDKHelper.getInstance()).isRobotMenuMessage(message))
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_ROBOT_MENU : MESSAGE_TYPE_SENT_ROBOT_MENU;
else
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_TXT : MESSAGE_TYPE_SENT_TXT;
}
if (message.getType() == EMMessage.Type.IMAGE) {
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_IMAGE : MESSAGE_TYPE_SENT_IMAGE;
}
if (message.getType() == EMMessage.Type.LOCATION) {
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_LOCATION : MESSAGE_TYPE_SENT_LOCATION;
}
if (message.getType() == EMMessage.Type.VOICE) {
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VOICE : MESSAGE_TYPE_SENT_VOICE;
}
if (message.getType() == EMMessage.Type.VIDEO) {
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_VIDEO : MESSAGE_TYPE_SENT_VIDEO;
}
if (message.getType() == EMMessage.Type.FILE) {
return message.direct == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_FILE : MESSAGE_TYPE_SENT_FILE;
}
return -1;// invalid
}
@SuppressLint("NewApi")
public View getView(final int position, View convertView, ViewGroup parent) {
final EMMessage message = getItem(position);
ChatType chatType = message.getChatType();
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = createViewByMessage(message, position);
if (message.getType() == EMMessage.Type.IMAGE) {
try {
holder.iv = ((ImageView) convertView.findViewById(R.id.iv_sendPicture));
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
holder.tv = (TextView) convertView.findViewById(R.id.percentage);
holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
} catch (Exception e) {
}
} else if (message.getType() == EMMessage.Type.TXT) {
try {
holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
// 这里是文字内容
holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent);
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
holder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
holder.tvList = (LinearLayout) convertView.findViewById(R.id.ll_layout);
} catch (Exception e) {
}
// 语音通话及视频通话
if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)
|| message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false)) {
holder.iv = (ImageView) convertView.findViewById(R.id.iv_call_icon);
holder.tv = (TextView) convertView.findViewById(R.id.tv_chatcontent);
}
} else if (message.getType() == EMMessage.Type.VOICE) {
try {
holder.iv = ((ImageView) convertView.findViewById(R.id.iv_voice));
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
holder.tv = (TextView) convertView.findViewById(R.id.tv_length);
holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
holder.iv_read_status = (ImageView) convertView.findViewById(R.id.iv_unread_voice);
} catch (Exception e) {
}
} else if (message.getType() == EMMessage.Type.LOCATION) {
try {
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
holder.tv = (TextView) convertView.findViewById(R.id.tv_location);
holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
} catch (Exception e) {
}
} else if (message.getType() == EMMessage.Type.VIDEO) {
try {
holder.iv = ((ImageView) convertView.findViewById(R.id.chatting_content_iv));
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
holder.tv = (TextView) convertView.findViewById(R.id.percentage);
holder.pb = (ProgressBar) convertView.findViewById(R.id.progressBar);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.size = (TextView) convertView.findViewById(R.id.chatting_size_iv);
holder.timeLength = (TextView) convertView.findViewById(R.id.chatting_length_iv);
holder.playBtn = (ImageView) convertView.findViewById(R.id.chatting_status_btn);
holder.container_status_btn = (LinearLayout) convertView.findViewById(R.id.container_status_btn);
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
} catch (Exception e) {
}
} else if (message.getType() == EMMessage.Type.FILE) {
try {
holder.iv_avatar = (ImageView) convertView.findViewById(R.id.iv_userhead);
holder.tv_file_name = (TextView) convertView.findViewById(R.id.tv_file_name);
holder.tv_file_size = (TextView) convertView.findViewById(R.id.tv_file_size);
holder.pb = (ProgressBar) convertView.findViewById(R.id.pb_sending);
holder.staus_iv = (ImageView) convertView.findViewById(R.id.msg_status);
holder.tv_file_download_state = (TextView) convertView.findViewById(R.id.tv_file_state);
holder.ll_container = (LinearLayout) convertView.findViewById(R.id.ll_file_container);
// 这里是进度值
holder.tv = (TextView) convertView.findViewById(R.id.percentage);
} catch (Exception e) {
}
try {
holder.tv_usernick = (TextView) convertView.findViewById(R.id.tv_userid);
} catch (Exception e) {
}
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 群聊时,显示接收的消息的发送人的名称
if ((chatType == ChatType.GroupChat || chatType == chatType.ChatRoom) && message.direct == EMMessage.Direct.RECEIVE){
//demo里使用username代码nick
holder.tv_usernick.setText(message.getFrom());
}
// 如果是发送的消息并且不是群聊消息,显示已读textview
if (!(chatType == ChatType.GroupChat || chatType == chatType.ChatRoom) && message.direct == EMMessage.Direct.SEND) {
holder.tv_ack = (TextView) convertView.findViewById(R.id.tv_ack);
holder.tv_delivered = (TextView) convertView.findViewById(R.id.tv_delivered);
if (holder.tv_ack != null) {
if (message.isAcked) {
if (holder.tv_delivered != null) {
holder.tv_delivered.setVisibility(View.INVISIBLE);
}
holder.tv_ack.setVisibility(View.VISIBLE);
} else {
holder.tv_ack.setVisibility(View.INVISIBLE);
// check and display msg delivered ack status
if (holder.tv_delivered != null) {
if (message.isDelivered) {
holder.tv_delivered.setVisibility(View.VISIBLE);
} else {
holder.tv_delivered.setVisibility(View.INVISIBLE);
}
}
}
}
} else {
// 如果是文本或者地图消息并且不是group messgae,chatroom message,显示的时候给对方发送已读回执
if ((message.getType() == Type.TXT || message.getType() == Type.LOCATION) && !message.isAcked && chatType != ChatType.GroupChat && chatType != ChatType.ChatRoom) {
// 不是语音通话记录
if (!message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)) {
try {
EMChatManager.getInstance().ackMessageRead(message.getFrom(), message.getMsgId());
// 发送已读回执
message.isAcked = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//设置用户头像
setUserAvatar(message, holder.iv_avatar);
switch (message.getType()) {
// 根据消息type显示item
case IMAGE: // 图片
handleImageMessage(message, holder, position, convertView);
break;
case TXT: // 文本
if (message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, false)
|| message.getBooleanAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, false))
// 音视频通话
handleCallMessage(message, holder, position);
else if(((DemoHXSDKHelper)HXSDKHelper.getInstance()).isRobotMenuMessage(message))
//含有列表的消息
handleRobotMenuMessage(message, holder, position);
else
handleTextMessage(message, holder, position);
break;
case LOCATION: // 位置
handleLocationMessage(message, holder, position, convertView);
break;
case VOICE: // 语音
handleVoiceMessage(message, holder, position, convertView);
break;
case VIDEO: // 视频
handleVideoMessage(message, holder, position, convertView);
break;
case FILE: // 一般文件
handleFileMessage(message, holder, position, convertView);
break;
default:
// not supported
}
if (message.direct == EMMessage.Direct.SEND) {
View statusView = convertView.findViewById(R.id.msg_status);
// 重发按钮点击事件
statusView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 显示重发消息的自定义alertdialog
Intent intent = new Intent(activity, AlertDialog.class);
intent.putExtra("msg", activity.getString(R.string.confirm_resend));
intent.putExtra("title", activity.getString(R.string.resend));
intent.putExtra("cancel", true);
intent.putExtra("position", position);
if (message.getType() == EMMessage.Type.TXT)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_TEXT);
else if (message.getType() == EMMessage.Type.VOICE)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VOICE);
else if (message.getType() == EMMessage.Type.IMAGE)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_PICTURE);
else if (message.getType() == EMMessage.Type.LOCATION)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_LOCATION);
else if (message.getType() == EMMessage.Type.FILE)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_FILE);
else if (message.getType() == EMMessage.Type.VIDEO)
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_VIDEO);
}
});
} else {
final String st = context.getResources().getString(R.string.Into_the_blacklist);
if(!((ChatActivity)activity).isRobot && chatType != ChatType.ChatRoom){
// 长按头像,移入黑名单
holder.iv_avatar.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Intent intent = new Intent(activity, AlertDialog.class);
intent.putExtra("msg", st);
intent.putExtra("cancel", true);
intent.putExtra("position", position);
activity.startActivityForResult(intent, ChatActivity.REQUEST_CODE_ADD_TO_BLACKLIST);
return true;
}
});
}
}
TextView timestamp = (TextView) convertView.findViewById(R.id.timestamp);
if (position == 0) {
timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime())));
timestamp.setVisibility(View.VISIBLE);
} else {
// 两条消息时间离得如果稍长,显示时间
EMMessage prevMessage = getItem(position - 1);
if (prevMessage != null && DateUtils.isCloseEnough(message.getMsgTime(), prevMessage.getMsgTime())) {
timestamp.setVisibility(View.GONE);
} else {
timestamp.setText(DateUtils.getTimestampString(new Date(message.getMsgTime())));
timestamp.setVisibility(View.VISIBLE);
}
}
return convertView;
}