参考资料:http://www.rongcloud.cn/docs/android.html#新建消息
1. 自定义消息实体 –RedPackageMessage(一个自定义的红包消息)
package com.onetoo.www.onetoo.bean.chat;import android.os.Parcel;import android.util.Log;import org.json.JSONException;import org.json.JSONObject;import java.io.UnsupportedEncodingException;import io.rong.common.ParcelUtils;import io.rong.imlib.MessageTag;import io.rong.imlib.model.MessageContent;/** * Created by longShun on 2017/2/24. *//** 注解名:MessageTag ;属性:value ,flag; value 即 ObjectName 是消息的唯一标识不可以重复,* 开发者命名时不能以 RC 开头,避免和融云内置消息冲突;flag 是用来定义消息的可操作状态。*如下面代码段,自定义消息名称 CustomizeMessage ,vaule 是 app:custom ,* flag 是 MessageTag.ISCOUNTED | MessageTag.ISPERSISTED 表示消息计数且存库。* app:RedPkgMsg: 这是自定义消息类型的名称,测试的时候用"app:RedPkgMsg";* */@MessageTag(value = "app:RedPkgMsg", flag = MessageTag.ISCOUNTED | MessageTag.ISPERSISTED)public class RedPackageMessage extends MessageContent{ //自定义的属性 PRivate String title; private String storeName; private String desc1; private String desc2; /* * * 实现 encode() 方法,该方法的功能是将消息属性封装成 json 串, * 再将 json 串转成 byte 数组,该方法会在发消息时调用,如下面示例代码: * */ @Override public byte[] encode() { JSONObject jsonObj = new JSONObject(); try { jsonObj.put("title", this.getTitle()); jsonObj.put("storeName",this.getStoreName()); jsonObj.put("desc1",this.getDesc1()); jsonObj.put("desc2",this.getDesc2()); } catch (JSONException e) { Log.e("JSONException", e.getMessage()); } try { return jsonObj.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } /* * 覆盖父类的 MessageContent(byte[] data) 构造方法,该方法将对收到的消息进行解析, * 先由 byte 转成 json 字符串,再将 json 中内容取出赋值给消息属性。 * */ public RedPackageMessage(byte[] data) { String jsonStr = null; try { jsonStr = new String(data, "UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } try { JSONObject jsonObj = new JSONObject(jsonStr); if (jsonObj.has("title")) setTitle(jsonObj.optString("title")); if (jsonObj.has("storeName")) setStoreName(jsonObj.optString("storeName")); if (jsonObj.has("desc1")) setDesc1(jsonObj.optString("desc1")); if (jsonObj.has("desc2")) setDesc2(jsonObj.optString("desc2")); } catch (JSONException e) { Log.d("JSONException", e.getMessage()); } } //给消息赋值。 public RedPackageMessage(Parcel in) { setTitle(ParcelUtils.readFromParcel(in));//该类为工具类,消息属性 //这里可继续增加你消息的属性 setStoreName(ParcelUtils.readFromParcel(in));//该类为工具类,消息属性 setDesc1(ParcelUtils.readFromParcel(in));//该类为工具类,消息属性 setDesc2(ParcelUtils.readFromParcel(in));//该类为工具类,消息属性 } /** * 读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。 */ public static final Creator<RedPackageMessage> CREATOR = new Creator<RedPackageMessage>() { @Override public RedPackageMessage createFromParcel(Parcel source) { return new RedPackageMessage(source); } @Override public RedPackageMessage[] newArray(int size) { return new RedPackageMessage[size]; } }; @Override public int describeContents() { return 0; } /** * 将类的数据写入外部提供的 Parcel 中。 * @param dest 对象被写入的 Parcel。 * @param flags 对象如何被写入的附加标志。 */ @Override public void writeToParcel(Parcel dest, int flags) { ParcelUtils.writeToParcel(dest, getTitle()); ParcelUtils.writeToParcel(dest, getStoreName()); ParcelUtils.writeToParcel(dest, getDesc1()); ParcelUtils.writeToParcel(dest, getDesc2()); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getStoreName() { return storeName; } public void setStoreName(String storeName) { this.storeName = storeName; } public String getDesc1() { return desc1; } public void setDesc1(String desc1) { this.desc1 = desc1; } public String getDesc2() { return desc2; } public void setDesc2(String desc2) { this.desc2 = desc2; }}2.自定义消息提供者
package com.onetoo.www.onetoo.bean.chat;import android.content.Context;import android.text.Spannable;import android.text.SpannableString;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import com.onetoo.www.onetoo.R;import io.rong.imkit.emoticon.AndroidEmoji;import io.rong.imkit.model.ProviderTag;import io.rong.imkit.model.UIMessage;import io.rong.imkit.widget.provider.IContainerItemProvider;import io.rong.imlib.model.Message;import io.rong.imlib.model.MessageContent;import io.rong.message.TextMessage;/** * Created by longShun on 2017/2/24. * desc新建一个消息类继承 IContainerItemProvider.MessageProvider 类,实现对应接口方法, * 1.注意开头的注解! * 2.注意泛型! */@ProviderTag( messageContent = RedPackageMessage.class,(这里是你自定义的消息实体) showReadState = true)public class RedPackageItemProvider extends IContainerItemProvider.MessageProvider<RedPackageMessage> { public RedPackageItemProvider() { } @Override public View newView(Context context, ViewGroup viewGroup) { //这就是展示在会话界面的自定义的消息的布局 View view = LayoutInflater.from(context).inflate(R.layout.item_redpackage_message, null); ViewHolder holder = new ViewHolder(); holder.tvTitle = (TextView) view.findViewById(R.id.tv_title); holder.tvStoreName = (TextView) view.findViewById(R.id.tv_store_name); holder.tvDesc1 = (TextView) view.findViewById(R.id.tv_desc1); holder.tvDesc2 = (TextView) view.findViewById(R.id.tv_desc2); view.setTag(holder); return view; } @Override public void bindView(View view, int i, RedPackageMessage redPackageMessage, UIMessage message) { //根据需求,适配数据 ViewHolder holder = (ViewHolder) view.getTag(); if (message.getMessageDirection() == Message.MessageDirection.SEND) {//消息方向,自己发送的 //holder.message.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_right); } else { //holder.message.setBackgroundResource(io.rong.imkit.R.drawable.rc_ic_bubble_left); } //AndroidEmoji.ensure((Spannable) holder.message.getText());//显示消息中的 Emoji 表情。 //holder.tvTitle.setText(redPackageMessage.getTitle()); holder.tvStoreName.setText(redPackageMessage.getStoreName()); //holder.tvDesc1.setText(redPackageMessage.getDesc1()); //holder.tvDesc2.setText(redPackageMessage.getDesc2()); } @Override public Spannable getContentSummary(RedPackageMessage redPackageMessage) { return new SpannableString(redPackageMessage.getDesc1()); } @Override public void onItemClick(View view, int i, RedPackageMessage redPackageMessage, UIMessage uiMessage) { } @Override public void onItemLongClick(View view, int i, RedPackageMessage redPackageMessage, UIMessage uiMessage) { //实现长按删除等功能,咱们直接复制融云其他provider的实现 String[] items1;//复制,删除 items1 = new String[]{view.getContext().getResources().getString(io.rong.imkit.R.string.rc_dialog_item_message_copy), view.getContext().getResources().getString(io.rong.imkit.R.string.rc_dialog_item_message_delete)}; OptionsPopupDialog.newInstance(view.getContext(), items1).setOptionsPopupDialogListener(new OptionsPopupDialog.OnOptionsItemClickedListener() { public void onOptionsItemClicked(int which) { if (which == 0) { ClipboardManager clipboard = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(content.getContent());//这里是自定义消息的消息属性 } else if (which == 1) { RongIM.getInstance().deleteMessages(new int[]{message.getMessageId()}, (RongIMClient.ResultCallback) null); } } }).show(); } private static class ViewHolder { TextView tvTitle, tvStoreName, tvDesc1, tvDesc2; }}3.注意自定义消息的布局:
写法一(会出问题):整体就一层布局,那么效果图如下,红包布局会占满右边所有空间
写法二(正常):整体布局外面再嵌套一层,显示正常,如图所示,至于原因,暂时还不清楚。
4.注册消息类型以及消息提供者
RongIM.init(this); //注意,要在初始化之后注册 RongIM.registerMessageType(RedPackageMessage.class); RongIM.registerMessageTemplate(new RedPackageItemProvider());5.官网测试
新闻热点
疑难解答