android环信easeui自定义消息--名片

来源:互联网 发布:阿里云客服怎么工作 编辑:程序博客网 时间:2024/06/06 09:25

前言

现在应用中即时通信的功能在app中应用的十分广泛,在即时通信这一块,公司在开发初期多数会选择第三方的库:环信/融云,特别是初创型公司的最爱,关于环信的基本使用,官方文档已经十分清晰了,下面我记录下我开发中的使用之:发送自定义消息—名片
先上效果图:
效果图

开发之路

集成easeui

easeui的集成,官方文档以及写得很详细了,这里不再多述。
easeui为我们提供了一个EaseChatFragment,我们可以直接使用这个EaseChatFragment,也可以自己写一个ChatFragment,继承EaseChatFragment并调用EaseChatFragmentHelper接口。这里我们为了方便,直接使用easeui提供的EaseChatFragment。

进入聊天页面

直接使用EaseChatFragment,通过Bundle,传入一系列参数(聊天模式,聊天对象)

//new出EaseChatFragment或其子类的实例mChatFragment = new EaseChatFragment();//传入参数Bundle args = new Bundle();//设置为单聊,否则单聊时,消息发送不成功args.putInt(EaseConstant.EXTRA_CHAT_TYPE, EaseConstant.CHATTYPE_SINGLE);userName = SPUtils.getString(this, SPUtils.KEY_USERNAME, "123");//555,123是已经注册的环信账号args.putString(EaseConstant.EXTRA_USER_ID, userName.equals("123")?"555":"123");mChatFragment.setArguments(args);replaceFragment(R.id.fl_container, mChatFragment);

发送扩展消息

根据官方文档,我们需要发送一个扩展消息,如下

//发名片(扩展消息)EMMessage message = EMMessage.createTxtSendMessage("我的名片",userName.equals("123")?"555":"123");//设置聊天模式为单聊message.setChatType(EMMessage.ChatType.Chat);//设置消息携带的一系列参数,为以后显示名片做准备message.setAttribute("title", "title_title_title_title");message.setAttribute("records", true);message.setAttribute("icon", R.mipmap.ic_launcher);message.setAttribute("senderid", userName.equals("123")?"555":"123");message.setAttribute("text", "您的名片已经发送");EMClient.getInstance().chatManager().sendMessage(message);ToastUtil.showShort(getApplicationContext(),"名片发送成功");

消息布局

我们需要写一个接收消息的布局,写一个发送消息的布局。两个布局文件中的相对应的控件id要保持一致,方便之后代码中设置内容,这里只贴出发送消息的布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="center_horizontal"    android:orientation="vertical"    android:paddingTop="13dp" >    <TextView        android:id="@+id/timestamp"        style="@style/chat_text_date_style"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:paddingLeft="20dp" >        <ImageView            android:id="@+id/iv_userhead"            android:layout_width="@dimen/size_avatar"            android:layout_height="@dimen/size_avatar"            android:layout_alignParentRight="true"            android:layout_alignParentTop="true"            android:layout_marginRight="5dp"            android:background="@drawable/ease_default_avatar"            android:scaleType="fitXY" />        <LinearLayout            android:id="@+id/bubble"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="5dp"            android:layout_toLeftOf="@id/iv_userhead"            android:layout_toRightOf="@+id/ll_loading"            android:background="@drawable/ease_chatto_bg" >            <ImageView                android:scaleType="fitXY"                android:id="@+id/ease_chat_item_share_img"                android:layout_width="50dp"                android:layout_height="50dp"                android:layout_margin="5dp"                android:src="@drawable/ease_chat_item_file" />            <LinearLayout                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_gravity="center_vertical"                android:layout_marginLeft="7dp"                android:gravity="center_vertical"                android:orientation="vertical" >                <TextView                    android:id="@+id/tv_title_name"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center_vertical"                    android:ellipsize="middle"                    android:singleLine="true"                    android:textColor="#000"                    android:textSize="15sp" />            </LinearLayout>        </LinearLayout>        <ProgressBar            android:id="@+id/progress_bar"            android:layout_width="25dp"            android:layout_height="25dp"            android:layout_centerVertical="true"            android:layout_toLeftOf="@id/bubble"            android:visibility="visible" />        <ImageView            android:id="@+id/msg_status"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_toLeftOf="@id/bubble"            android:clickable="true"            android:src="@drawable/ease_msg_state_failed_resend"            android:visibility="invisible" />        <TextView            android:id="@+id/tv_ack"            style="@style/chat_text_name_style"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_toLeftOf="@id/tv_chatcontent"            android:text="@string/text_ack_msg"            android:textSize="12sp"            android:visibility="invisible" />        <TextView            android:id="@+id/tv_delivered"            style="@style/chat_text_name_style"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_toLeftOf="@id/tv_chatcontent"            android:text="@string/text_delivered_msg"            android:textSize="12sp"            android:visibility="invisible" />    </RelativeLayout></LinearLayout>

自定义消息内容

有了消息布局,我们需要在发送和接收时,控制消息内容,easeui提供了EaseChatRow,我们只需要继承这个类,就可以在消息发送和接收时,控制消息体:在onInflateView()方法中加载布局,在onFindViewById()方法中获取控件,在onSetUpView()中改变展示内容,在onBubbleClick()方法中写消息被点击时的逻辑

public class EaseChatRowCard extends EaseChatRow {    ImageView img;//图片    TextView title;//title    private TextView text;    public EaseChatRowCard(Context context, EMMessage message, int position, BaseAdapter adapter) {        super(context, message, position, adapter);    }    /**     * 加载布局     */    @Override    protected void onInflatView() {        inflater.inflate(message.direct() == EMMessage.Direct.RECEIVE ?                R.layout.ease_row_received_card : R.layout.ease_row_sent_card, this);    }    /**     * 实例化控件     */    @Override    protected void onFindViewById() {        title = (TextView) findViewById(R.id.tv_title_name);        img = (ImageView) findViewById(R.id.ease_chat_item_share_img);        text = (TextView) findViewById(R.id.timestamp);    }    /**     * 更新适配器     */    @Override    protected void onUpdateView() {        adapter.notifyDataSetChanged();    }    /**     * 设置内容     */    @Override    protected void onSetUpView() {        try {            String titleString = message.getStringAttribute("title");            title.setText(titleString);            img.setImageResource(message.getIntAttribute("icon",R.drawable.ic_launcher));            //消息状态变化            handleTextMessage();        } catch (HyphenateException e) {            e.printStackTrace();        }    }    protected void handleTextMessage() {        if (message.direct() == EMMessage.Direct.SEND) {            setMessageSendCallback();            switch (message.status()) {                case CREATE:                    progressBar.setVisibility(View.GONE);                    statusView.setVisibility(View.VISIBLE);                    break;                case SUCCESS:                    progressBar.setVisibility(View.GONE);                    statusView.setVisibility(View.GONE);                    break;                case FAIL:                    progressBar.setVisibility(View.GONE);                    statusView.setVisibility(View.VISIBLE);                    break;                case INPROGRESS:                    progressBar.setVisibility(View.VISIBLE);                    statusView.setVisibility(View.GONE);                    break;                default:                    break;            }        }else{            if(!message.isAcked() && message.getChatType() == EMMessage.ChatType.Chat){                try {                    EMClient.getInstance().chatManager().ackMessageRead(message.getFrom(), message.getMsgId());                } catch (HyphenateException e) {                    e.printStackTrace();                }            }        }    }    @Override    protected void onBubbleClick() {        Toast.makeText(context, "点击了", Toast.LENGTH_SHORT).show();    }}

展示消息—EaseMessageAdapter

消息体已经写好了,那么在消息发送和接收时,我们还需要一个适配器去展示消息。这就需要easeui中的一个重要的类—EaseMessageAdapter。
在EaseMessageAdapter中的getViewTypeCount()方法中将默认的14种方法,改成16(包括自定义接收消息和发送消息)

public int getViewTypeCount() {    if(customRowProvider != null && customRowProvider.getCustomChatRowTypeCount() > 0){        //14改成16        return customRowProvider.getCustomChatRowTypeCount() + 16;    }       //14改成16       return 16;   }

在getItemViewType(int position)方法中,增加消息类型:

public int getItemViewType(int position) {    EMMessage message = getItem(position);     if (message == null) {        return -1;    }    if(customRowProvider != null && customRowProvider.getCustomChatRowType(message) > 0){        //13改成15        return customRowProvider.getCustomChatRowType(message) + 15;    }    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;        }else if (message.getBooleanAttribute("records", false)){//自定义消息扩展            return message.direct() == EMMessage.Direct.RECEIVE ? MESSAGE_TYPE_RECV_EXTENDS : MESSAGE_TYPE_SEND_EXTENDS;        }        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;    }    return -1;// invalid}

之前我们写一个自定义的ChatRow,我们需要在EaseMessageAdapter中的createChatRow方法中创建方法体

protected EaseChatRow createChatRow(Context context, EMMessage message, int position) {    EaseChatRow chatRow = null;    if(customRowProvider != null && customRowProvider.getCustomChatRow(message, position, this) != null){        return customRowProvider.getCustomChatRow(message, position, this);    }    switch (message.getType()) {    case TXT:        if(message.getBooleanAttribute(EaseConstant.MESSAGE_ATTR_IS_BIG_EXPRESSION, false)){            chatRow = new EaseChatRowBigExpression(context, message, position, this);        }else if (message.getBooleanAttribute("records", false)){//自定义消息扩展chatRow = new EaseChatRowShare(context,message,position,this);} else{            chatRow = new EaseChatRowText(context, message, position, this);        }        break;    case LOCATION:        chatRow = new EaseChatRowLocation(context, message, position, this);        break;    case FILE:        chatRow = new EaseChatRowFile(context, message, position, this);        break;    case IMAGE:        chatRow = new EaseChatRowImage(context, message, position, this);        break;    case VOICE:        chatRow = new EaseChatRowVoice(context, message, position, this);        break;    case VIDEO:        chatRow = new EaseChatRowVideo(context, message, position, this);        break;    default:        break;    }    return chatRow;}

消息刷新

以上基本可以完成发送名片的功能,存在一个小缺陷,消息在发送时,未刷新,所以我们需要手动刷新,在EaseChatFragment可以获取EaseChatMessageList进行刷新。
在EaseChatFragment写一个获取EaseChatMessageList 的方法

public EaseChatMessageList getMessageList(){    return messageList;}

在发送自定义消息后,进行刷新消息

...mChatFragment.getMessageList().refresh();//刷新数据,否则发送时,无法接收到ToastUtil.showShort(getApplicationContext(),"名片发送成功");

以上就完成了集成easeui后进行发送名片

原创粉丝点击