以掷骰子为例
首先,先定义一个自定义消息的类型
public interface CustomAttachmentType {
// 多端统一
int Guess = 1;
int SnapChat = 2;
int Sticker = 3;
int RTS = 4;
int Crops=5;//骰子
}
第二步,定义一个自定义消息附件的基类,负责解析你的自定义消息的公用字段,比如类型等 。
注意: 实现 MsgAttachment 接口的成员都要实现 Serializable。
public abstract class CustomAttachment implements MsgAttachment {
protected int type;
CustomAttachment(int type) {
this.type = type;
}
public void fromJson(JSONObject data) {
if (data != null) {
parseData(data);
}
}
@Override
public String toJson(boolean send) {
return CustomAttachParser.packData(type, packData());
}
public int getType() {
return type;
}
protected abstract void parseData(JSONObject data);
protected abstract JSONObject packData();
}
第三步,继承这个基类,实现“骰子”的附件类型。
注意,成员变量都要实现 Serializable。
public class CrapsAttachment extends CustomAttachment{
public enum Craps {
one(1, "1"),
two(2, "2"),
three(3, "3"),
four(4,"4"),
five(5,"5"),
six(6,"6"),
;
private int value;
private String desc;
Craps(int value, String desc) {
this.value = value;
this.desc = desc;
}
static Craps enumOfValue(int value) {
for (Craps direction : values()){
if (direction.getValue() == value) {
return direction;
}
}
return one;
}
public int getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
private Craps value;
public CrapsAttachment() {
super(CustomAttachmentType.Guess);
random();
}
@Override
protected void parseData(JSONObject data) {
value = Craps.enumOfValue(data.getIntValue("value"));
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put("value", value.getValue());
return data;
}
private void random() {
int value = new Random().nextInt(6) + 1;
this.value = Craps.enumOfValue(value);
}
public Craps getValue() {
return value;
}
}
第四步,实现自定义消息的附件解析器。
public class CustomAttachParser implements MsgAttachmentParser {
private static final String KEY_TYPE = "type";
private static final String KEY_DATA = "data";
@Override
public MsgAttachment parse(String json) {
CustomAttachment attachment = null;
try {
JSONObject object = JSON.parseObject(json);
int type = object.getInteger(KEY_TYPE);
JSONObject data = object.getJSONObject(KEY_DATA);
switch (type) {
case CustomAttachmentType.Crops:
attachment = new CrapsAttachment();
default:
attachment = new DefaultCustomAttachment();
break;
}
if (attachment != null) {
attachment.fromJson(data);
}
} catch (Exception e) {
}
return attachment;
}
public static String packData(int type, JSONObject data) {
JSONObject object = new JSONObject();
object.put(KEY_TYPE, type);
if (data != null) {
object.put(KEY_DATA, data);
}
return object.toJSONString();
}
}
第五步,将自定义消息展示UI上(当然这里显示的文字,如果想要显示成图片,可以参考demo)
public class MsgViewHolderCrops extends MsgViewHolderText{
@Override
protected String getDisplayText() {
//实例化一个attachment
CrapsAttachment attachment = (CrapsAttachment)message.getAttachment();
return attachment.getValue().getDesc() + "点!";
}
}
第六步,发送自定义消息
public class CrapsAction extends BaseAction{
public CrapsAction(){
super(R.drawable.message_plus_crops_selector, R.string.input_panel_crops);
}
@Override
public void onClick() {
CrapsAttachment attachment = new CrapsAttachment();
IMMessage message = MessageBuilder.createCustomMessage(
getAccount(), getSessionType(), attachment.getValue().getDesc(), attachment
);
sendMessage(message);
}
}
第七步,将该附件解析器注册到 SDK 中。为了保证生成历史消息时能够正确解析自定义附件,注册一般应放在 Application 的 onCreate 中完成
NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
第八步,注册扩展消息类型的显示ViewHolder,由于这里使用我们UIKIT,所以也需要注册到Application的onCreate中
NimUIKit.registerMsgItemViewHolder(CrapsAttachment.class, MsgViewHolderCrops.class);
第九步,添加“骰子”的按钮到“+”号中,Demo是在SessionHelper.java里面,定制的单聊界面。
ArrayList<BaseAction> actions = new ArrayList<>();
actions.add(new CrapsAction());