环信3.0自定义扩展消息

最近公司项目需要用到环信,早就听说过环信文档写的比较坑,继承过后才发现哪里是坑,简直是无底洞。。。

项目需求是这样的,菜单中有一个房源按钮,点击后弹出房源信息列表,点击列表中的Item将此条Item的概括信息发送个对方。目前环信的消息类型有文本、图片、地理位置、语音视频、红包,提供的已经很全面了,可是我需要像京东、今日头条分享好友似的那种消息类型。所以我们以文本消息为基础,在它上面进行我们的自定义扩展消息。

文档都快翻烂了,还是没找到有价值的资料(文档内容太旧了,好多方法、类都换新了)。没办法,自己翻看环信提供的ChatDemoUi3.0源码和百度资料。皇天不负有心人,终于搞定了。

一、定义字段

首先,定义我们扩展消息需要的字段
public class HouseInfoConstant {
    public static final String houseInfoExtType = "houseInfoExtType";//房源信息扩展
    public static final String houseInfoTitle = "houseInfoTitle";//房源标题
    public static final String houseInfoImgUrl = "houseInfoImgUrl";//房源图片
    public static final String houseInfoDesc = "houseInfoDesc";//房源信息小文字描述
    public static final String houseInfoObjectId = "houseInfoObjectId";//房源信息ID
}
这些字段在后面会经常用到,所以提取到一个类中。

二、定义常量

接下来去我们的ChatFragment中定义几个常量
    private static final int REQUEST_CODE_SELECT_HOUSEINFOEXT = 99;
    private static final int MESSAGE_TYPE_RECV_HOUSEINFOEXT_CALL = 5;
    private static final int MESSAGE_TYPE_SEND_HOUSEINFOEXT_CALL = 6;
    private static final int ITEM_HOUSEINFO = 13;

三、注册按钮

在我们的ChatFragment中复写 registerExtendMenuItem()方法注册按钮
protected void registerExtendMenuItem() {
        super.registerExtendMenuItem();
        inputMenu.registerExtendMenuItem("房源列表", R.mipmap.ic_launcher, ITEM_HOUSEINFO, extendMenuItemClickListener);
    }

四、绑定菜单按钮点击事件

注册按钮后还要绑定它的点击事件,通过我们的ChatFragment实现EaseChatFragmentHelper接口的onExtendMenuItemClick方法来绑定
我是在setUpView中绑定的这个接口
protected void setUpView() {
        setChatFragmentHelper(this);
        super.setUpView();
    }
public boolean onExtendMenuItemClick(int itemId, View view) {
        switch (itemId) {
            case ITEM_HOUSEINFO://房源信息
                startActivityForResult(new Intent(getActivity(), HouseInfoListActivity.class), REQUEST_CODE_SELECT_HOUSEINFOEXT);
                break;
            default:
                break;
        }
        return false;
    }

五、覆写onActivityResult()方法

通过点击上面的房源列表Item返回我们需要的房源信息,并将这条信息以我们的扩展消息类型发送出去
public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_CODE_SELECT_HOUSEINFOEXT:
                    if (data != null) {
                        String title = data.getStringExtra("title");
                        String imgUrl = data.getStringExtra("img");
                        String objectId = data.getStringExtra("objectId");
                        String desc = "我在正和兴发现一套不错的房源,推荐你也来看看吧!";
                        EMMessage message = EMMessage.createTxtSendMessage("房源卡片", toChatUsername);
                        message.setAttribute(HouseInfoConstant.houseInfoExtType, true);//设置扩展字段
                        message.setAttribute(HouseInfoConstant.houseInfoTitle, title);//将title设置到扩展字段
                        message.setAttribute(HouseInfoConstant.houseInfoImgUrl, imgUrl);//将imgUrl设置到扩展字段
                        message.setAttribute(HouseInfoConstant.houseInfoObjectId, objectId);//将objectId设置到扩展字段
                        message.setAttribute(HouseInfoConstant.houseInfoDesc, desc);//将desc设置到扩展字段
                        EMClient.getInstance().chatManager().sendMessage(message);
                    }
                    break;
            }
        }
    }

六、定义我们自己的扩展消息提供者CustomChatRowProvider

用来返回我们需要的扩展消息类型载体ChatRow,自定义的ChatRow在后面给出
private final class CustomChatRowProvider implements EaseCustomChatRowProvider {
        @Override
        public int getCustomChatRowTypeCount() {
            return 2;
        }

        @Override
        public int getCustomChatRowType(EMMessage message) {
            if (message.getType() == EMMessage.Type.TXT) {
                if (message.getBooleanAttribute(HouseInfoConstant.houseInfoExtType, false)) {
                    return message.direct() == EMMessage.Direct.RECEIVE ? ChatFragment.MESSAGE_TYPE_RECV_HOUSEINFOEXT_CALL : ChatFragment.MESSAGE_TYPE_SEND_HOUSEINFOEXT_CALL;
                }
            }
            return 0;
        }


        @Override
        public EaseChatRowPresenter getCustomChatRow(EMMessage message, int position, BaseAdapter adapter) {
            if (message.getType() == EMMessage.Type.TXT) {
                if (message.getBooleanAttribute(HouseInfoConstant.houseInfoExtType, false)) {
                    //发送房源信息卡片
                    return new EaseChatHouseInfoCallPresenter();
                }
            }
            return null;
        }

    }
解释一下,getCustomChatRowTypeCount()方法意思我们的新定义了几种消息类型,因为消息有接收方和发送方,所以一种ChatRow对应两种类型。
getCustomChatRowType(EMMessage message),这个方法是获取消息的类型,通过代码也不难看出是判断消息类型是发送还是接收。
getCustomChatRow(EMMessage message, int position, BaseAdapter adapter),获取自定义的ChatRow对象。
七、绑定我们的扩展消息提供者
 @Override
    public EaseCustomChatRowProvider onSetCustomChatRowProvider() {
        return new CustomChatRowProvider();
    }

八、实现自己的ChatRow(重点,这个是核心)

我们扩展消息的载体,可以理解为ListView的Item。没有Item,ListView啥也不是。
public class ChatRowHouseInfo extends EaseChatRow {

    private TextView title, desc;
    private ImageView img;

    public ChatRowHouseInfo(Context context, EMMessage message, int position, BaseAdapter adapter) {
        super(context, message, position, adapter);
    }

    /*
    填充layout
     */
    @Override
    protected void onInflateView() {
        inflater.inflate(message.direct() == EMMessage.Direct.RECEIVE ?
                R.layout.ease_row_received_houseinfo_call : R.layout.ease_row_send_houseinfo_call, this);
    }

    /*
    查找chatrow中的控件
     */
    @Override
    protected void onFindViewById() {
        title = (TextView) findViewById(R.id.house_info_card_title);
        desc = (TextView) findViewById(R.id.house_info_card_desc);
        img = (ImageView) findViewById(R.id.house_info_card_img);
    }

    /*
    消息状态改变,刷新listView
     */
    @Override
    protected void onViewUpdate(EMMessage msg) {
        adapter.notifyDataSetChanged();
    }


    @Override
    protected void onSetUpView() {
        EMTextMessageBody textMessageBody = (EMTextMessageBody) message.getBody();
        message.getStringAttribute(HouseInfoConstant.houseInfoExtType, null);
        String titleStr = message.getStringAttribute(HouseInfoConstant.houseInfoTitle, null);
        String descStr = message.getStringAttribute(HouseInfoConstant.houseInfoDesc, null);
        String imgurlStr = message.getStringAttribute(HouseInfoConstant.houseInfoImgUrl, null);
        if (!TextUtils.isEmpty(titleStr))
            title.setText(titleStr);
        if (!TextUtils.isEmpty(descStr))
            desc.setText(descStr);
        ImageLoaderKit.loadImage(imgurlStr, img);
    }
}

九、包装自定义的ChatRow

public class EaseChatHouseInfoCallPresenter extends EaseChatRowPresenter {
    @Override
    protected EaseChatRow onCreateChatRow(Context cxt, EMMessage message, int position, BaseAdapter adapter) {
        return new ChatRowHouseInfo(cxt, message, position, adapter);
    }
}
网上的资料都没有这一步骤,都是在扩展消息提供者中直接返回ChatRow实例,我是翻看环信最新Demo源码才搞清楚这里。

十、总结

到这里,自定义扩展消息就完成了,没有文档真心伤不起啊,今晚要加个鸡腿犒劳犒劳自己了。还有,要想实现自定义扩展消息的点击事件的,通过覆写onMessageBubbleClick(EMMessage message)
效果图:



猜你喜欢

转载自blog.csdn.net/ever69/article/details/78731108
今日推荐