上一篇我们把发送红包的具体流程过了一下,这篇我就开始说一下红包消息体具体是怎么写的 废话多说上货。
上一篇链接:Android基于环信自定义消息实现转账红包(一)
1.我们需要在环信的easeui包里的EaseMessageAdapter 里写自定义红包消息
private static final int MESSAGE_TYPE_SEND_REDPACK = 14;
private static final int MESSAGE_TYPE_RECV_REDPACK = 15;
//环信本来有14个 我们新加了两个所以+2 一个是发送的,一个是接收的。
@Override
public int getViewTypeCount() {
if (customRowProvider != null && customRowProvider.getCustomChatRowTypeCount() > 0) {
return customRowProvider.getCustomChatRowTypeCount() + 14 + 2;
}
return 14 + 2;
}
//在getItemViewType中也要+一下
/**
* get type of item
*/
@Override
public int getItemViewType(int position) {
EMMessage message = getItem(position);
if (message == null) {
return -1;
}
if (customRowProvider != null && customRowProvider.getCustomChatRowType(message) > 0) {
return customRowProvider.getCustomChatRowType(message) + 13 + 2;
}
if (message.getType() == EMMessage.Type.TXT) {
//文本消息体
if (message.getBooleanAttribute(EaseConstant.MESSAGE_ATTR_IS_BIG_EXPRESSION, false)) {
return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_EXPRESSION : MESSAGE_TYPE_SENT_EXPRESSION;
}
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;
}
//我们是自定义消息体"redPacket"我们看着很眼熟吧 没错这就是我们上一篇构造消息的时候命名的
if (message.getType() == EMMessage.Type.CUSTOM) {
if (message.getBooleanAttribute("redPacket", false)) {
//红包
return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_REDPACK : MESSAGE_TYPE_SEND_REDPACK;
}
}
return -1;// invalid
}
2.我们需要在EaseChatRowPresenter createChatRowPresenter(EMMessage message, int position)里写
switch (message.getType()) {
case CUSTOM:
if (message.getBooleanAttribute("redPacket", false)) {
//红包
presenter = new EaseChatHongbaoPresenter();//这个需要自己创建(仿照环信已经写好的在写一个自己的presenter)
}
break;
case TXT:
if (message.getBooleanAttribute(EaseConstant.MESSAGE_ATTR_IS_BIG_EXPRESSION, false)) {
presenter = new EaseChatBigExpressionPresenter();
} else {
presenter = new EaseChatTextPresenter();
}
break;
case LOCATION:
presenter = new EaseChatLocationPresenter();
break;
case FILE:
presenter = new EaseChatFilePresenter();
break;
case IMAGE:
presenter = new EaseChatImagePresenter();
break;
case VOICE:
presenter = new EaseChatVoicePresenter();
break;
case VIDEO:
presenter = new EaseChatVideoPresenter();
break;
default:
break;
}
public class EaseChatHongbaoPresenter extends EaseChatRowPresenter {
@Override
protected EaseChatRow onCreateChatRow(Context cxt, EMMessage message, int position, BaseAdapter adapter) {
return new EaseChatRowHongbao(cxt, message, position, adapter);//EaseChatRowHongbao也是我们仿照环信原有的写的
}
@Override
public void onBubbleClick(final EMMessage message) {
//这里是红包的点击事件,就收者点击进入收红包页面,发送者不能点击,消息体中有自己定义的参数可以传给收款页面
EMCustomMessageBody body = (EMCustomMessageBody) message.getBody();
if (message.direct() == EMMessage.Direct.RECEIVE){
EMCustomMessageBody body = (EMCustomMessageBody) message.getBody();
String money = body.getParams().get("redPacketNum");
String redPacketHxNo = body.getParams().get("redPacketHxNo");
String redPacketRemark = body.getParams().get("redPacketRemark");
Intent intent = new Intent(getContext(), ShoukActivity.class);
intent.putExtra("money",money);
intent.putExtra("redPacketHxNo",redPacketHxNo);
intent.putExtra("toChatUsername",message.getFrom());
intent.putExtra("ChatUsername",message.getTo());
getContext().startActivity(intent);
}
}
}
3.接下来就是一个关键的地方那就是布局+页面控制(未收款、已收款、已退回)这其中还分是发送方 还是接收方 UI都不一样,因为我们自己看到的是一个样,对方看到的是另一个样子(我的样式如下,小伙伴们的布局可以根据项目需求定)。
public class EaseChatRowHongbao extends EaseChatRow {
private TextView locationView,bz,ysk,xia_text;
private EMCustomMessageBody body;
private RelativeLayout bubble;
private ImageView img_ysk;
private String money,redPacketRemark;
public EaseChatRowHongbao(Context context, EMMessage message, int position, BaseAdapter adapter) {
super(context, message, position, adapter);
}
@Override
protected void onInflateView() {
//这里就是两个布局 一个是接收 一个是发送
inflater.inflate(message.direct() == EMMessage.Direct.RECEIVE ?
R.layout.ease_row_received_hongbao : R.layout.ease_row_sent_hongbao, this);
}
@Override
protected void onFindViewById() {
//在这里初始化控件
locationView = (TextView) findViewById(R.id.money_text);
bz = (TextView) findViewById(R.id.bz);
bubble = findViewById(R.id.bubble);
ysk = (TextView) findViewById(R.id.ysk);
xia_text = (TextView) findViewById(R.id.xia_text);
img_ysk = (ImageView) findViewById(R.id.img_ysk);
}
@Override
protected void onSetUpView() {
//获取到body从而拿到消息体中的数据
body = (EMCustomMessageBody) message.getBody();
money = body.getParams().get("redPacketNum");
redPacketRemark = body.getParams().get("redPacketRemark");
//我们可以在这里通过接口获取到当前红包的状态,从而改变红包的样式。
//我们可以通过一下代码判断是发送方还是接收方
if (message.direct() == EMMessage.Direct.RECEIVE){
}
}
@Override
protected void onViewUpdate(EMMessage msg) {
adapter.notifyDataSetChanged();
switch (msg.status()) {
case CREATE:
onMessageCreate();
break;
case SUCCESS:
onMessageSuccess();
break;
case FAIL:
onMessageError();
break;
case INPROGRESS:
onMessageInProgress();
break;
}
}
private void onMessageCreate() {
progressBar.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE);
}
private void onMessageSuccess() {
progressBar.setVisibility(View.GONE);
statusView.setVisibility(View.GONE);
}
private void onMessageError() {
progressBar.setVisibility(View.GONE);
statusView.setVisibility(View.VISIBLE);
}
private void onMessageInProgress() {
progressBar.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE);
}
/*
* listener for map clicked
*/
protected class MapClickListener implements View.OnClickListener {
String address;
public MapClickListener(String address) {
this.address = address;
}
@Override
public void onClick(View v) {
}
}
}
结合上篇文章我们就可以实现发送红包功能 ,这里面大部分功能必须通过后台的配合才可以实现,我们虽然基于环信的自定义消息 ,自定义消息也就是个样式,实现红包状态的切换还得需要后台配合完成。还有一点如果小伙伴的项目也有ios端 那么字段啥的一定要和ios端一致 否则就会出现崩溃,因为如果消息字段不一致,环信是找不到这个消息类型的,所以必须一致才可以。
最后再补充一点,我们聊天列表 会有消息类型展示,比如收到图片消息,就展示图片,收到文字 就展示收到的文字消息, 表情,就会展示表情等等,那么我们是红包 收到的应该是如图这样的效果,红包转账。
我们需要在EaseConversationAdapter中getview中 其他消息体设置的地方加上
if (EaseSmileUtils.getSmiledText(getContext(), EaseCommonUtils.getMessageDigest(lastMessage, (this.getContext()))).toString().equals("")){
EMCustomMessageBody body;
body = (EMCustomMessageBody) lastMessage.getBody();
holder.message.setText(body.event());
}
其实还有一些我没写,如收红包方如何收红包等,实现的思路和发送一样,就是刷新红包状态,发送已收红包通知,然后刷新消息列表即可,如果有小伙伴不懂的可以品论区留言,有需要的我还可以为大家写一篇收红包的具体实现,谢谢大家,再见!