easeui 自定义消息布局

在使用easeui集成即时通讯的过程中,easeui提供的消息布局可能不能满足我们的需求,就想QQ分享那种布局,今天就这个问题写一下。

QQ聊天界面分享

1、咱们来实现这种布局,首先如果我们要把这种消息和其他的消息区分开,那就需要使用环信提供的消息扩展。使用方法如下:
//发送一条扩展消息
String username=list.get(position).groupid;//对方的id
EMMessage message = EMMessage.createTxtSendMessage("分享的扩展消息",username);
message.setChatType(EMMessage.ChatType.GroupChat);
message.setAttribute("title", title);
message.setAttribute("icon", icon);
message.setAttribute("activityID", activityID);
message.setAttribute("senderid", SPUtils.getString(SPUtils.USER_ID));
EMClient.getInstance().chatManager().sendMessage(message);
T.shortToast(getApplicationContext(),"分享成功");

好了,这样就成功发送了一条和其他消息不一样的消息。

2、接下来,在easeui中做一些提前的准备,我们要去写两个布局,一般使用原有的布局文件去修改,为什么要写两个布局呢?因为要写一个接收消息的布局,写一个发送消息的布局。注意两个布局文件中的相对应的控件id要保持一致!接收方的ease_row_received_share.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    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"
        android:layout_gravity="center" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:paddingRight="20dp" >

        <ImageView
            android:id="@+id/iv_userhead"
            android:layout_width="@dimen/size_avatar"
            android:layout_height="@dimen/size_avatar"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="50dp"
            android:background="@drawable/ease_default_avatar"
            android:scaleType="fitXY" />

        <TextView
            android:id="@+id/tv_userid"
            style="@style/chat_text_name_style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:textSize="@dimen/chat_nick_text_size"
            android:layout_toRightOf="@id/iv_userhead"
            android:visibility="gone" />

        <LinearLayout
            android:id="@+id/bubble"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:layout_marginLeft="50dp"
            android:layout_marginRight="60dp"
            android:layout_toLeftOf="@+id/progress_bar"
            android:layout_toRightOf="@id/iv_userhead"
            android:layout_below="@+id/tv_userid"
            android:background="@drawable/ease_chatfrom_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:singleLine="true"
                    android:ellipsize="middle"
                    android:textColor="#000"
                    android:textSize="15sp" />
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

然后是发送方的布局代码ease_row_sent_share.xml

<?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_marginLeft="60dp"
            android:layout_width="match_parent"
            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>

        <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>
3、写好布局之后,咱们要写一个对应的类去控制这些控件。可能有人问上边的布局为啥控件要用相同的id,这里看到代码就知道为什么了。EaseChatRowShare.java具体代码如下:
package com.hyphenate.easeui.widget.chatrow;

import android.content.Context;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.hyphenate.chat.EMMessage;
import com.hyphenate.easeui.R;
import com.hyphenate.exceptions.HyphenateException;
import com.squareup.picasso.Picasso;

public class EaseChatRowShare extends  EaseChatRow {

    ImageView img;//图片
    TextView title;//title

    public EaseChatRowShare(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_share : R.layout.ease_row_sent_share, this);
    }

    /**
     * 实例化控件
     */
    @Override
    protected void onFindViewById() {
        title = (TextView) findViewById(R.id.tv_title_name);
        img = (ImageView) findViewById(R.id.ease_chat_item_share_img);
    }


    /**
     * 更新适配器
     */
    @Override
    protected void onUpdateView() {
        adapter.notifyDataSetChanged();
    }

    /**
     * 设置内容
     */
    @Override
    protected void onSetUpView() {
        try {
            String titleString = message.getStringAttribute("title");
            String iconString = message.getStringAttribute("icon");
            String activityIDString = message.getStringAttribute("activityID");
            title.setText(titleString);
            Picasso.with(context).load(iconString).into(img);
        } catch (HyphenateException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onBubbleClick() {
    }
}

看到这里,大家都能看清楚了,原因是在onInflateView()方法中,通过判断接收消息或者发送消息来加载不同的布局文件,所以在下边的控件要保持相同的id。

4、咱们怎么来使用这个EaseChatRowShare呢,大家在看这个消息的适配器EaseMessageAdapter的时候,发现定义了好多布局类型,然后在按不同的消息类型去加载不同的条目。easeui在这个地方给开发者留好了自定义布局的开发方式,大家看下边这个方法:
    /**
     * get number of message type, here 14 = (EMMessage.Type) * 2
     */
    public int getViewTypeCount() {
        if(customRowProvider != null && customRowProvider.getCustomChatRowTypeCount() > 0){
            return customRowProvider.getCustomChatRowTypeCount() + 14;
        }
        return 14;
    }

发现在customRowProvider 中写了一个customRowProvider.getCustomChatRowTypeCount() + 14; 这里的14是easeui内置的14种消息类型。然后我们去看这个 customRowProvider,是一个自定义消息的接口,好了,我们自己写一个类去实现EaseCustomChatRowProvider这个接口。CustomChatRowProvider代码如下:

package com.hyphenate.easeui.widget.chatrow;

import android.content.Context;
import android.widget.BaseAdapter;

import com.hyphenate.chat.EMMessage;
import com.hyphenate.exceptions.HyphenateException;

public class CustomChatRowProvider  implements EaseCustomChatRowProvider {

    private static final int MESSAGE_TYPE_SENDSHAREPIC = 1;//发送
    private static final int MESSAGE_TYPE_RECEIVEDSHAREPIC = 2;//接收

    private Context mContext;

    public CustomChatRowProvider(Context mContext) {
        this.mContext = mContext;
    }

    /**
     * 创建自定义的布局类型数量(返回值必须是类型的数量*2.包括接收布局和发送布局)
     * @return
     */
    @Override
    public int getCustomChatRowTypeCount() {
        return 2;
    }

    /**
     * 根据message的接收和发送  返回自定义的布局类型
     * @param message
     * @return
     */
    @Override
    public int getCustomChatRowType(EMMessage message) {
        //这里做个判断    如果能取到扩展字段    就返回消息类型
        try {
            message.getStringAttribute("title");
            return message.direct() == EMMessage.Direct.RECEIVE ?MESSAGE_TYPE_RECEIVEDSHAREPIC:MESSAGE_TYPE_SENDSHAREPIC;
        } catch (HyphenateException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 返回chatrow   每种文件的类型(图片、音频)  这里返回自定义的分享布局
     * @param message
     * @param position
     * @param adapter
     * @return
     */
    @Override
    public EaseChatRow getCustomChatRow(EMMessage message, int position, BaseAdapter adapter) {
        //同上    如果能取到扩展字段    就返回消息类型
        try {
            message.getStringAttribute("title");
            return new EaseChatRowShare(mContext, message, position, adapter);
        } catch (HyphenateException e) {
            e.printStackTrace();
        }
        return null;
    }
}
5、写好了这些,就让我们看看怎么用到CustomChatRowProvider 类,

在创建聊天的Fragment的时候,我们要设置Fragment的chatFragmentListener,然后去重写onSetCustomChatRowProvider()方法,具体代码如下:

        chatFragment = new EaseChatFragment();
        //设置聊天页面的自定义布局
        chatFragment.setChatFragmentListener(new EaseChatFragment.EaseChatFragmentHelper() {
            @Override
            public void onSetMessageAttributes(EMMessage message) {

            }

            @Override
            public void onEnterToChatDetails() {

            }

            @Override
            public void onAvatarClick(String username) {

            }

            @Override
            public void onAvatarLongClick(String username) {

            }

            @Override
            public boolean onMessageBubbleClick(EMMessage message) {
                return false;
            }

            @Override
            public void onMessageBubbleLongClick(EMMessage message) {

            }

            @Override
            public boolean onExtendMenuItemClick(int itemId, View view) {
                return false;
            }

            @Override
            public EaseCustomChatRowProvider onSetCustomChatRowProvider() {
                return new CustomChatRowProvider(GroupChatActivity.this);
            }
        });
6、到这里使用easeui实现自定义消息布局就实现了,咱们来看一下效果:

自定义消息布局效果

小伙伴们去使用吧!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值