一、前言
每条消息根据对方有没有在规定时间内容回复,在消息底部显示一句提示语。这需要不是很常见,不过碰到了,你是不是懵了,这可咋整。
需求是每种消息都需要这样的提示语,不单是文本消息。图片消息,小视频消息,语音消息等
二、效果图


不用在意双方发的消息对不上。截的是设计图。当然图片消息,其他消息也有这样的提示语的
三、解决思路
肯定是要自定义模板(MessageItemProvider)了的。但每个消息模板都要这样的需求,看是否有一个基类,这样统一处理比较好。结果还真有(BaseMessageItemProvider)。
方案:
- 自定义BaseMessageItemProvider(拷贝融云原来的全部代码,在合适的位置加上你的业务代码)
- 在rc_message_item布局加上显示那句话的textview
- 然后自定义每一种消息模板,然后它继承上面自定义的BaseMessageItemProvider
- 至于怎么判断出状态,你们研发团队自己讨论了(实在讨论不出方案的,可私信我)
四、给出MyBaseMessageItemProvider和其中的文本消息模板MyTextMessageItemProvider示例代码
MyBaseMessageItemProvider
public abstract class MyBaseMessageItemProvider<T extends MessageContent> implements IMessageProvider<T> {
private static final String TAG = "BaseMessageItemProvider";
protected MessageItemProviderConfig mConfig = new MessageItemProviderConfig();
public MyBaseMessageItemProvider() {
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_message_item, parent, false);
FrameLayout contentView = (FrameLayout)rootView.findViewById(R.id.rc_content);
ViewHolder contentViewHolder = this.onCreateMessageContentViewHolder(contentView, viewType);
if (contentViewHolder != null && contentView.getChildCount() == 0) {
contentView.addView(contentViewHolder.itemView);
}
return new MessageViewHolder(rootView.getContext(), rootView, contentViewHolder);
}
protected abstract ViewHolder onCreateMessageContentViewHolder(ViewGroup var1, int var2);
public boolean isItemViewType(UiMessage item) {
return this.isMessageViewType(item.getMessage().getContent());
}
public void bindViewHolder(ViewHolder holder, final UiMessage uiMessage, int position, List<UiMessage> list, final IViewProviderListener<UiMessage> listener) {
if (uiMessage != null && uiMessage.getMessage() != null && listener != null) {
LogUtils.INSTANCE.o("uiMessage",uiMessage);
Message message = uiMessage.getMessage();
holder.setVisible(R.id.rc_selected, uiMessage.isEdit());
holder.setVisible(R.id.rc_v_edit, uiMessage.isEdit());
if (uiMessage.isEdit()) {
holder.setSelected(R.id.rc_selected, uiMessage.isSelected());
holder.setOnClickListener(R.id.rc_v_edit, new View.OnClickListener() {
public void onClick(View v) {
listener.onViewClick(-10, uiMessage);
}
});
}
boolean isSender = uiMessage.getMessage().getMessageDirection().equals(Message.MessageDirection.SEND);
this.initTime(holder, position, list, message);
this.initUserInfo(holder, uiMessage, position, listener, isSender);
this.initContent(holder, isSender, uiMessage, position, listener, list);
this.initStatus(holder, uiMessage, position, listener, message, isSender, list);
this.initCusSendMessageFail(holder, isSender,position,message);
if (holder instanceof MessageViewHolder) {
this.bindMessageContentViewHolder(((MessageViewHolder)holder).getMessageContentViewHolder(), holder, (T) uiMessage.getMessage().getContent(), uiMessage, position, list, listener);
} else {
RLog.e("BaseMessageItemProvider", "holder is not MessageViewHolder");
}
uiMessage.setChange(false);
} else {
RLog.e("BaseMessageItemProvider", "uiMessage is null");
}
}
private void initTime(ViewHolder holder, int position, List<UiMessage> data, Message message) {
String time = RongDateUtils.getConversationFormatDate(message.getSentTime(), holder.getContext());
holder.setText(R.id.rc_time, time);
if (position == 0) {
holder.setVisible(R.id.rc_time, !(message.getContent() instanceof HistoryDividerMessage));
} else {
UiMessage pre = (UiMessage)data.get(position - 1);
if (pre.getMessage() != null && RongDateUtils.isShowChatTime(message.getSentTime(), pre.getMessage().getSentTime(), 180)) {
holder.setVisible(R.id.rc_time, true);
} else {
holder.setVisible(R.id.rc_time, false);
}
}
}
private void initUserInfo(final ViewHolder holder, final UiMessage uiMessage, int position, final IViewProviderListener<UiMessage> listener, boolean isSender) {
if (this.mConfig.showPortrait) {
holder.setVisible(R.id.rc_left_portrait, !isSender);
holder.setVisible(R.id.rc_right_portrait, isSender);
ImageView view = (ImageView)holder.getView(isSender ? R.id.rc_right_portrait :R.id.rc_left_portrait);
if (uiMessage.getUserInfo().getPortraitUri() != null) {
RongConfigCenter.featureConfig().getKitImageEngine().loadConversationPortrait(holder.getContext(), uiMessage.getUserInfo().getPortraitUri().toString(), view, uiMessage.getMessage());
}
holder.setOnClickListener(R.id.rc_left_portrait, new View.OnClickListener() {
public void onClick(View v) {
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
boolean result = RongConfigCenter.conversationConfig().getConversationClickListener().onUserPortraitClick(holder.getContext(), uiMessage.getMessage().getConversationType(), uiMessage.getUserInfo(), uiMessage.getMessage().getTargetId());
if (!result) {
listener.onViewClick(-5, uiMessage);
}
}
}
});
holder.setOnClickListener(R.id.rc_right_portrait, new View.OnClickListener() {
public void onClick(View v) {
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
boolean result = RongConfigCenter.conversationConfig().getConversationClickListener().onUserPortraitClick(holder.getContext(), uiMessage.getMessage().getConversationType(), uiMessage.getUserInfo(), uiMessage.getMessage().getTargetId());
if (!result) {
listener.onViewClick(-5, uiMessage);
}
}
}
});
holder.setOnLongClickListener(R.id.rc_left_portrait, new View.OnLongClickListener() {
public boolean onLongClick(View v) {
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
boolean result = RongConfigCenter.conversationConfig().getConversationClickListener().onUserPortraitLongClick(holder.getContext(), uiMessage.getMessage().getConversationType(), uiMessage.getUserInfo(), uiMessage.getMessage().getTargetId());
if (!result) {
return listener.onViewLongClick(-6, uiMessage);
}
}
return false;
}
});
holder.setOnLongClickListener(R.id.rc_right_portrait, new View.OnLongClickListener() {
public boolean onLongClick(View v) {
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
boolean result = RongConfigCenter.conversationConfig().getConversationClickListener().onUserPortraitLongClick(holder.getContext(), uiMessage.getMessage().getConversationType(), uiMessage.getUserInfo(), uiMessage.getMessage().getTargetId());
if (!result) {
return listener.onViewLongClick(-6, uiMessage);
}
}
return false;
}
});
if (!RongConfigCenter.conversationConfig().isShowReceiverUserTitle(uiMessage.getMessage().getConversationType())) {
holder.setVisible(R.id.rc_title, false);
} else if (!isSender) {
holder.setVisible(R.id.rc_title, true);
holder.setText(R.id.rc_title, !TextUtils.isEmpty(uiMessage.getNickname()) ? uiMessage.getNickname() : uiMessage.getUserInfo().getName());
} else {
holder.setVisible(R.id.rc_title, false);
}
} else {
holder.setVisible(R.id.rc_left_portrait, false);
holder.setVisible(R.id.rc_right_portrait, false);
holder.setVisible(R.id.rc_title, false);
}
}
private void initContent(final ViewHolder holder, boolean isSender, final UiMessage uiMessage, final int position, final IViewProviderListener<UiMessage> listener, final List<UiMessage> list) {
if (this.mConfig.showContentBubble) {
if (ChattingActivity.Companion.getExpireUidList() != null && ChattingActivity.Companion.getExpireUidList().size() > 0){
if (isSender){
//我发的
holder.setBackgroundRes(R.id.rc_content, ChattingActivity.Companion.getExpireUidList().contains(uiMessage.getUId()) ? R.drawable.rc_ic_bubble_right_grey : R.drawable.rc_ic_bubble_right);
} else {
holder.setBackgroundRes(R.id.rc_content, R.drawable.rc_ic_bubble_left);
}
} else {
holder.setBackgroundRes(R.id.rc_content, isSender ? R.drawable.rc_ic_bubble_right : R.drawable.rc_ic_bubble_left);
}
} else {
holder.getView(R.id.rc_content).setBackground((Drawable)null);
}
if (ChattingActivity.Companion.getExpireUidList() != null && ChattingActivity.Companion.getExpireUidList().size() > 0){
if (isSender){
//我发的
holder.setVisible(R.id.app_message_gold_right_status,ChattingActivity.Companion.getExpireUidList().contains(uiMessage.getUId()));
holder.setVisible(R.id.app_message_gold_left_status,false);
} else {
holder.setVisible(R.id.app_message_gold_left_status,ChattingActivity.Companion.getExpireUidList().contains(uiMessage.getUId()));
holder.setVisible(R.id.app_message_gold_right_status,false);
}
} else {
holder.setVisible(R.id.app_message_gold_left_status,false);
holder.setVisible(R.id.app_message_gold_right_status,false);
}
holder.setPadding(R.id.rc_content, 0, 0, 0, 0);
LinearLayout layout = (LinearLayout)holder.getView(R.id.rc_layout);
if (this.mConfig.centerInHorizontal) {
layout.setGravity(1);
} else {
layout.setGravity(isSender ? 8388613 : 8388611);
}
holder.setOnClickListener(R.id.rc_content, new View.OnClickListener() {
public void onClick(View v) {
boolean result = false;
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
result = RongConfigCenter.conversationConfig().getConversationClickListener().onMessageClick(holder.getContext(), v, uiMessage.getMessage());
}
if (!result) {
result = onItemClick(((MessageViewHolder)holder).getMessageContentViewHolder(), (T) uiMessage.getMessage().getContent(), uiMessage, position, list, listener);
if (!result) {
listener.onViewClick(-9, uiMessage);
}
}
}
});
holder.setOnLongClickListener(R.id.rc_content, new View.OnLongClickListener() {
public boolean onLongClick(View v) {
boolean result = false;
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
result = RongConfigCenter.conversationConfig().getConversationClickListener().onMessageLongClick(holder.getContext(), v, uiMessage.getMessage());
}
if (!result) {
result = onItemLongClick(((MessageViewHolder)holder).getMessageContentViewHolder(), (T) uiMessage.getMessage().getContent(), uiMessage, position, list, listener);
if (!result) {
return listener.onViewLongClick(-4, uiMessage);
}
}
return false;
}
});
}
private void initCusSendMessageFail(ViewHolder holder,boolean isSender,int position, Message message){
if (message.getContent().getExtra() != null && message.getContent().getExtra().contains("appSendState") && isSender){
CustomizeMsgExtra customizeMsgExtra = new Gson().fromJson(message.getContent().getExtra(),CustomizeMsgExtra.class);
if (customizeMsgExtra != null && customizeMsgExtra.getAppSendState() == 1){
holder.setVisible(R.id.app_send_msg_fail, true);
holder.setVisible(R.id.rc_warning, false); //正常不会
holder.setOnClickListener(R.id.app_send_msg_fail, new View.OnClickListener() {
public void onClick(View v) {
message.setExtra("isAdded");
MyImagePlugin.selectDataSize = 1;
if (message.getContent() != null){
MessageContent mc = message.getContent();
if (mc instanceof HQVoiceMessage || mc instanceof ImageMessage || mc instanceof SightMessage || mc instanceof GIFMessage ){
RongIM.getInstance().sendMediaMessage(message, "", "", new IRongCallback.ISendMediaMessageCallback() {
@Override
public void onProgress(Message message, int i) {
}
@Override
public void onCanceled(Message message) {
}
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, RongIMClient.ErrorCode errorCode) {
}
});
} else {
RongIM.getInstance().sendMessage(message,"","",null);
}
} else {
RongIM.getInstance().sendMessage(message,"","",null);
}
}
});
} else {
holder.setVisible(R.id.app_send_msg_fail, false);
}
} else {
holder.setVisible(R.id.app_send_msg_fail, false);
}
}
private void initStatus(ViewHolder holder, final UiMessage uiMessage, int position, final IViewProviderListener<UiMessage> listener, Message message, boolean isSender, List<UiMessage> list) {
if (this.mConfig.showWarning && !ResendManager.getInstance().needResend(uiMessage.getMessage().getMessageId())) {
if (isSender && uiMessage.getState() == 1) {
holder.setVisible(R.id.rc_warning, true);
holder.setOnClickListener(R.id.rc_warning, new View.OnClickListener() {
public void onClick(View v) {
listener.onViewClick(-1, uiMessage);
}
});
} else {
holder.setVisible(R.id.rc_warning, false);
}
} else {
holder.setVisible(R.id.rc_warning, false);
}
if (this.mConfig.showProgress) {
if (isSender && uiMessage.getState() == 2) {
holder.setVisible(R.id.rc_progress, true);
} else if (isSender && uiMessage.getState() == 1 && ResendManager.getInstance().needResend(uiMessage.getMessage().getMessageId())) {
holder.setVisible(R.id.rc_progress, true);
} else {
holder.setVisible(R.id.rc_progress, false);
}
} else {
holder.setVisible(R.id.rc_progress, false);
}
this.initReadStatus(holder, uiMessage, position, listener, message, isSender, list);
}
protected abstract void bindMessageContentViewHolder(ViewHolder var1, ViewHolder var2, T var3, UiMessage var4, int var5, List<UiMessage> var6, IViewProviderListener<UiMessage> var7);
protected abstract boolean onItemClick(ViewHolder var1, T var2, UiMessage var3, int var4, List<UiMessage> var5, IViewProviderListener<UiMessage> var6);
protected boolean onItemLongClick(ViewHolder holder, T t, UiMessage uiMessage, int position, List<UiMessage> list, IViewProviderListener<UiMessage> listener) {
return false;
}
private void initReadStatus(ViewHolder holder, final UiMessage uiMessage, int position, final IViewProviderListener<UiMessage> listener, Message message, boolean isSender, List<UiMessage> list) {
LogUtils.INSTANCE.i("initReadStatus",RongConfigCenter.conversationConfig().isShowReadReceipt(message.getConversationType())+"\t"+this.mConfig.showReadState+"\t"+isSender+"\t"+(message.getSentStatus() == Message.SentStatus.READ));
if (RongConfigCenter.conversationConfig().isShowReadReceipt(message.getConversationType()) && this.mConfig.showReadState && isSender && message.getSentStatus() == Message.SentStatus.READ) {
holder.setVisible(R.id.rc_read_receipt, true);
} else {
holder.setVisible(R.id.rc_read_receipt, false);
}
if (RongConfigCenter.conversationConfig().isShowReadReceiptRequest(message.getConversationType()) && this.showReadReceiptRequest(message) && isSender && !TextUtils.isEmpty(message.getUId())) {
boolean isLastSentMessage = true;
for(int i = position + 1; i < list.size(); ++i) {
if (((UiMessage)list.get(i)).getMessage().getMessageDirection() == Message.MessageDirection.SEND) {
isLastSentMessage = false;
break;
}
}
long serverTime = System.currentTimeMillis() - RongIMClient.getInstance().getDeltaTime();
if (serverTime - message.getSentTime() >= (long)(RongConfigCenter.conversationConfig().rc_read_receipt_request_interval * 1000) || !isLastSentMessage || message.getReadReceiptInfo() != null && message.getReadReceiptInfo().isReadReceiptMessage()) {
holder.setVisible(R.id.rc_read_receipt_request, false);
} else {
holder.setVisible(R.id.rc_read_receipt_request, true);
holder.setOnClickListener(R.id.rc_read_receipt_request, new View.OnClickListener() {
public void onClick(View v) {
listener.onViewClick(-2, uiMessage);
}
});
}
if (message.getReadReceiptInfo() != null && message.getReadReceiptInfo().isReadReceiptMessage()) {
if (message.getReadReceiptInfo().getRespondUserIdList() != null) {
holder.setText(R.id.rc_read_receipt_status, message.getReadReceiptInfo().getRespondUserIdList().size() + " " + holder.getContext().getString(R.string.rc_read_receipt_status));
} else {
holder.setText(R.id.rc_read_receipt_status, "0 " + holder.getContext().getString(R.string.rc_read_receipt_status));
}
holder.setVisible(R.id.rc_read_receipt_status, true);
holder.setOnClickListener(R.id.rc_read_receipt_status, new View.OnClickListener() {
public void onClick(View v) {
ConversationClickListener conversationClickListener = RongConfigCenter.conversationConfig().getConversationClickListener();
if (conversationClickListener == null || !conversationClickListener.onReadReceiptStateClick(v.getContext(), uiMessage.getMessage())) {
listener.onViewClick(-3, uiMessage);
}
}
});
} else {
holder.setVisible(R.id.rc_read_receipt_status, false);
}
} else {
holder.setVisible(R.id.rc_read_receipt_request, false);
holder.setVisible(R.id.rc_read_receipt_status, false);
}
}
protected boolean showReadReceiptRequest(Message message) {
return message != null && message.getContent() != null && message.getContent() instanceof TextMessage;
}
protected abstract boolean isMessageViewType(MessageContent var1);
public boolean isSummaryType(MessageContent messageContent) {
return this.isMessageViewType(messageContent);
}
public boolean showSummaryWithName() {
return this.mConfig.showSummaryWithName;
}
public static class MessageViewHolder extends ViewHolder {
private ViewHolder mMessageContentViewHolder;
public MessageViewHolder(Context context, View itemView, ViewHolder messageViewHolder) {
super(context, itemView);
this.mMessageContentViewHolder = messageViewHolder;
}
public ViewHolder getMessageContentViewHolder() {
return this.mMessageContentViewHolder;
}
}}
在initContent方法中我发的就是我的业务处理代码
MyTextMessageItemProvider
public class MyTextMessageItemProvider extends MyBaseMessageItemProvider<TextMessage> {
public MyTextMessageItemProvider() {
this.mConfig.showReadState = true;
}
protected ViewHolder onCreateMessageContentViewHolder(ViewGroup parent, int viewType) {
View textView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_text_message_item, parent, false);
return new ViewHolder(parent.getContext(), textView);
}
protected void bindMessageContentViewHolder(final ViewHolder holder, ViewHolder parentHolder, TextMessage message, final UiMessage uiMessage, int position, List<UiMessage> list, IViewProviderListener<UiMessage> listener) {
final TextView view = (TextView)holder.getView(R.id.rc_text);
if (TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == 1) {
view.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
}
view.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
if (uiMessage.getMessage().getMessageDirection().equals(Message.MessageDirection.SEND)){
view.setTextColor(parentHolder.getContext().getResources().getColor(R.color.white));
view.setPadding(CUtils.INSTANCE.dp2px(parentHolder.getContext(),12), CUtils.INSTANCE.dp2px(parentHolder.getContext(),12),
CUtils.INSTANCE.dp2px(parentHolder.getContext(),20),CUtils.INSTANCE.dp2px(parentHolder.getContext(),12));
} else {
if (ChattingActivity.Companion.getExpireUidList() != null && ChattingActivity.Companion.getExpireUidList().size() > 0){
view.setTextColor(ChattingActivity.Companion.getExpireUidList().contains(uiMessage.getUId())?parentHolder.getContext().getResources().getColor(R.color.color_AEAEB2):parentHolder.getContext().getResources().getColor(R.color.rc_text_main_color));
} else {
view.setTextColor(parentHolder.getContext().getResources().getColor(R.color.rc_voice_color));
}
view.setPadding(CUtils.INSTANCE.dp2px(parentHolder.getContext(),20), CUtils.INSTANCE.dp2px(parentHolder.getContext(),12),
CUtils.INSTANCE.dp2px(parentHolder.getContext(),12),CUtils.INSTANCE.dp2px(parentHolder.getContext(),12));
}
view.setTag(uiMessage.getMessageId());
if (uiMessage.getContentSpannable() == null) {
SpannableStringBuilder spannable = TextViewUtils.getSpannable(message.getContent(), new TextViewUtils.RegularCallBack() {
public void finish(SpannableStringBuilder spannable) {
uiMessage.setContentSpannable(spannable);
if (view.getTag().equals(uiMessage.getMessageId())) {
view.post(new Runnable() {
public void run() {
view.setText(uiMessage.getContentSpannable());
}
});
}
}
});
uiMessage.setContentSpannable(spannable);
}
view.setText(uiMessage.getContentSpannable());
view.setMovementMethod(new LinkTextViewMovementMethod(new ILinkClickListener() {
public boolean onLinkClick(String link) {
boolean result = false;
if (RongConfigCenter.conversationConfig().getConversationClickListener() != null) {
result = RongConfigCenter.conversationConfig().getConversationClickListener().onMessageLinkClick(holder.getContext(), link, uiMessage.getMessage());
}
if (result) {
return true;
} else {
String str = link.toLowerCase();
if (str.startsWith("http") || str.startsWith("https")) {
RouteUtils.routeToWebActivity(view.getContext(), link);
result = true;
}
return result;
}
}
}));
view.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
ViewParent parent = view.getParent();
if (parent instanceof View) {
((View)parent).performClick();
}
}
});
view.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View view) {
ViewParent parent = view.getParent();
return parent instanceof View ? ((View)parent).performLongClick() : false;
}
});
}
protected boolean onItemClick(ViewHolder holder, TextMessage message, UiMessage uiMessage, int position, List<UiMessage> list, IViewProviderListener<UiMessage> listener) {
return false;
}
protected boolean isMessageViewType(MessageContent messageContent) {
return messageContent instanceof TextMessage && !messageContent.isDestruct();
}
public Spannable getSummarySpannable(Context context, TextMessage message) {
if (message != null && !TextUtils.isEmpty(message.getContent())) {
String content = message.getContent();
content = content.replace("\n", " ");
if (content.length() > 100) {
content = content.substring(0, 100);
}
return new SpannableString(AndroidEmoji.ensure(content));
} else {
return new SpannableString("");
}
}}
这个没有做任何处理,就继承MyBaseMessageItemProvider。
有问题可私信我。
网友评论