可以自定义的区域说明

聊天窗口

位置 定制点 定制方式
顶部标题栏 整个标题栏(支持隐藏) 实现接口
消息气泡 文本消息和语音消息 实现接口
消息中URL URL点击事件 实现接口
消息中数字字符串 点击事件 实现接口
底部消息栏“+” +”内增加选项 实现接口
自定义消息 展示、点击和长按事件 实现接口
地理位置消息 消息展示、点击和长按事件 实现接口
语音消息播放 使用听筒或者扬声器模式播放语音消息 实现接口
自定义消息展示 不包含头像的自定义消息展示 实现接口
背景 背景颜色或图片 实现接口
聊天界面头像样式 圆角正方形、直角正方形、圆形 实现接口
聊天底部工具栏(ChattingReplyBar) 允许自定义高度,隐藏语音表情发送按钮 实现接口
聊天底部工具栏扩展(ChattingReplyBar) 允许自定义插件item位置,添加新的item,修改原有item,设置是否隐藏,设置点击事件 实现接口
表情扩展 可以添加自定义Emoji表情或者图片表情 方法调用
默认头像修改 默认头像图片 实现接口
聊天窗口顶部 聊天窗口顶部悬浮自定义view 实现接口
商品消息 自定义商品消息展示样式 实现接口
文本消息文字颜色 自定义文本消息的文字颜色 实现接口
会话列表和聊天窗口dimens 自定义会话列表和聊天窗口部分dimens 修改资源文件
打开聊天窗口 打开聊天窗口自动发送一条消息,支持本地隐藏 实现接口
消息时间 自定义时间文案 实现接口

自定义相关,主要用到的类:

聊天窗口:IMChattingPageUI, IMChattingPageOperateion

自定义效果图说明

聊天窗口UI定制展示

具体请参考工程NotificationInitSampleHelper

单聊页面UI定制化

文本消息与图片消息的气泡背景图设置

//设置消息的聊天气泡背景处理器,可以自定义设置文本以及图片消息的背景图,详细参见demo中的 ChattingUICustomSample 类
//第一步:新增类 ChattingUICustomSample
public class ChattingUICustomSample extends IMChattingPageUI{
/**
 * 设置消息气泡背景图,需要.9图
 * @param conversation 当前消息所在会话
 * @param message      需要设置背景的消息
 * @param self         是否是自己发送的消息,true:自己发送的消息, false:别人发送的消息
 * @return  0: 默认背景 -1:透明背景(无背景) >0:使用用户设置的背景图
 */
@Override
public int getMsgBackgroundResId(YWConversation conversation, YWMessage message, boolean self) {
    int msgType = message.getSubType();
    if (msgType == YWMessage.SUB_MSG_TYPE.IM_TEXT || msgType == YWMessage.SUB_MSG_TYPE.IM_AUDIO){
        if (self){
            return R.drawable.demo_talk_pop_r_bg;
        } else {
            return R.drawable.demo_talk_pop_l_bg;
        }
    } else if (msgType == YWMessage.SUB_MSG_TYPE.IM_IMAGE){
        if (self){
            return R.drawable.demo_talk_pic_pop_r_bg;
        } else {
            return R.drawable.demo_talk_pic_pop_l_bg;
        }
    } else if (msgType == YWMessage.SUB_MSG_TYPE.IM_VIDEO){
        if (self){
            return R.drawable.demo_talk_pic_pop_r_bg;
        } else {
            return R.drawable.demo_talk_pic_pop_l_bg;
        }
    } else if (msgType == YWMessage.SUB_MSG_TYPE.IM_GEO){
        if (self){
            return R.drawable.aliwx_comment_r_bg;
        } else {
            return R.drawable.aliwx_comment_l_bg;
        }
    } else if (msgType == YWMessage.SUB_MSG_TYPE.IM_P2P_CUS || msgType == YWMessage.SUB_MSG_TYPE.IM_TRIBE_CUS){
        if (self){
            return -1;
        } else {
            return -1;
        }
    }
    return super.getMsgBackgroundResId(conversation, message, self);
//第二步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_UI_POINTCUT,ChattingCustomAdviceSample.class);

自定义聊天界面回复栏(ChattingReplyBar)

选择性展示

新增根据会话类型选择性隐藏ChattingReplyBar的接口,其它item隐藏请使用adjustCustomInputViewPlugins()方法

示例代码在ChattingUICustomSample.java

/**
     * 是否隐藏底部ChattingReplyBar
     * @param conversation
     * @return
     */
    @Override
    public boolean needHideChattingReplyBar(YWConversation conversation) {
        return false;
    }
/**
     * 返回自定义ChattingReplyBar高度(单位为dp)
     * @return
     *     如果返回值小于等于0,则使用默认值
     */
    @Override
    public int getCustomChattingReplyBarHeight() {
        return 0;
    }
/**
     * 返回自定义聊天输入框高度(单位为dp)
     * @return
     *     如果返回值小于等于0,则使用默认值
     */
    @Override
    public int getCustomChattingInputEditTextHeight() {
        return 0;
    }

自定义聊天底部工具栏(ChattingReplyBar)扩展

/**
     * 修改ChattingReplyBar上的item,可以修改属性或者新增。如果开发者相同类型的会话plugin一样,则可以缓存pluginItems,
     * 在该方法调用时直接用缓存pluginItems替换掉参数中的pluginItems,替换方式为先removeAll,再addAll
     * 可以修改的属性包括:
     *  顺序,setIndex(int)方式
     *  是否显示(YWInputViewPlugin#setNeedHide(boolean))
     *  Item对应的View的基本操作,
     *
     *     SDK默认按钮的id为:
     *     YWChattingPlugin.ReplyBarPlugin#VOICE_VIEW
     *     YWChattingPlugin.ReplyBarPlugin#INPUT_EDIT_TEXT
     *     YWChattingPlugin.ReplyBarPlugin#FACE_VIEW
     *     YWChattingPlugin.ReplyBarPlugin#EXPAND_VIEW
     *
     *
     * 如果新增则创建一个{@link YWInputViewPlugin}并添加到replyBarItems。
     * @param conversation ChattingReplyBar所在会话,如果开发者需要可以根据会话类型对ChattingReplyBar的item进行调整
     * @param pluginItems item列表,初始是包含sdk默认提供的4个item:语音按钮、输入框、表情按钮、”+号“按钮,顺序索引为0,1,2,3
     * @return 使用sdk默认顺序则无需任何操作
     */
    @Override
    public List<YWInputViewPlugin> adjustCustomInputViewPlugins(final Fragment fragment, YWConversation conversation, List<YWInputViewPlugin> pluginItems) {
        if (pluginItems != null && pluginItems.size() > 0) {
            //对默认项进行操作,可以使用id判断具体是哪一个
            for (YWInputViewPlugin plugin : pluginItems) {
                if (plugin.getId() == YWChattingPlugin.ReplyBarPlugin.VOICE_VIEW) {
                    plugin.setNeedHide(true);//隐藏语音输入按钮
                }
            }
            //自定义新增的plugin只需要在布局中设置marginLeft即可
            final View plugin = LayoutInflater.from(fragment.getActivity()).inflate(R.layout.demo_extra_item_layout, null);
            //TODO 新增项id必须从4开始
            final YWInputViewPlugin pluginToAdd = new YWInputViewPlugin(plugin, 4);
            plugin.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(fragment.getActivity(), "你点击了Id为:" + pluginToAdd.getId() + "的新增item", Toast.LENGTH_LONG).show();
                }
            });
            pluginToAdd.setIndex(0);//在设置index时,如果新增项和默认pluginItem一样则开发者添加的显示在前
            pluginItems.add(pluginToAdd);
        }
    }

主动设置聊天窗口底部工具栏

自定义默认头像

示例代码在ChattingUICustomSample.java

/**
     * 返回单聊默认头像资源Id
     * @return
     *      0:使用SDK默认提供的
     */
    @Override
    public int getDefaultHeadImageResId() {
        return 0;
    }

标题栏定制

开发者可以替换整个聊天窗口的标题栏。
具体参考demo工程ChattingUICustomSample

自定义回复栏插件

默认提供“拍照”,“选择图片”两种方式。开发者可以根据需求新增item
详细参见demo中的 ChattingCustomAdviceSample 类 实现方法:

//第一步:新增类,返回自定义的View
public class ChattingOperationCustomSample extends IMChattingPageOperateion
public List<ReplyBarItem> getReplybarItems(Fragment pointcut,YWConversation conversation) {
    List<ReplyBarItem> replyBarItems = new ArrayList<ReplyBarItem>();
    if(conversation.getConversationType()==YWConversationType.P2P){
        ReplyBarItem replyBarItem = new ReplyBarItem();
        replyBarItem.setItemId(1);
        replyBarItem.setItemImageRes(R.drawable.aliwx_s001);
        replyBarItem.setItemLabel("自定义的item1");
        replyBarItems.add(replyBarItem1);

    }
    return replyBarItems;
}
//当自定义的item点击时的回调
public void onReplyBarItemClick(Fragment pointcut,ReplyBarItem item,YWConversation conversation) {
    Toast.makeText(pointcut.getActivity(), "title button click!"+item.getItemId(), Toast.LENGTH_SHORT).show();

}
//第二步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class);

聊天界面中消息中含点击url的行为的回调

此功能可实现开发者希望自己处理消息中点击URL的点击响应,比如用内部webview打开,而非默认三方浏览器 详细参见demo中的 ChattingOperationCustomSample类 实现方法:

//第一步:新增类并继承自 IMChattingPageOperateion,同时重写onUrlClick方法
public class ChattingCustomAdviceSample extends IMChattingPageOperateion
public boolean onUrlClick(Fragment fragment, YWMessage message, String url,YWConversation conversation) {
    Toast.makeText(fragment.getActivity(),"用户点击了url:"+url, Toast.LENGTH_LONG).show();
    return false;
}
//第二步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class);

聊天界面中自定义地理位置消息的显示

此功能可实现开发者希望自己处理地理位置消息的显示、点击和长按行为 详细参见demo中的 ChattingOperationCustomSample 类 实现方法:

//第一步:新增类,实现地理位置消息的显示、点击和长按行为
public class ChattingCustomAdviceSample extends IMChattingPageOperateion{
@Override
public View getCustomGeoMessageView(Fragment fragment, YWMessage msg) {
    YWGeoMessageBody messageBody = (YWGeoMessageBody)message.getMessageBody();
    String content = "纬度: " + messageBody.getLatitude() + ", 经度: " + messageBody.getLongitude() + ", 地址: " + messageBody.getAddress();
    LinearLayout layout = (LinearLayout) View.inflate(
            DemoApplication.getApplication(),
            R.layout.demo_custom_tribe_msg_layout, null);
    TextView textView = (TextView) layout.findViewById(R.id.msg_content);
    textView.setText(content);
    return layout;
    }

//第二步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class);

聊天界面中自定义消息的显示

此功能可实现开发者希望自己处理自定义消息的显示和点击行为 详细参见demo中的 ChattingOperationCustomSample类 实现方法:

//第一步:用户创建自定义消息
public static YWMessage createCustomMessage(YWConversationType type) {
    // 发送自定义消息
    YWMessageBody messageBody = new YWMessageBody();
    // 请注意这里不一定要是JSON格式,这里纯粹是为了演示的需要
    JSONObject object = new JSONObject();
    try {
        object.put("myData1", "自定义数据" + count++);
        object.put("type", 1);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    messageBody.setContent(object.toString());// 用户要发送的自定义消息,SDK不关心具体的格式,比如用户可以发送JSON格式
    messageBody.setSummary("消息摘要");// 可以理解为消息的标题,用于显示会话列表和消息通知栏
    // 注意,这里是群自定义消息
    if (type == YWConversationType.Tribe) {
        return YWMessageChannel.createTribeCustomMessage(messageBody);
    }
    // 注意,这里是单聊自定义消息
    return YWMessageChannel.createCustomMessage(messageBody);
}

//第二步:新增类,实现自定义消息的显示
public class ChattingOperationCustomSampleextends IMChattingPageOperateion{
@Override
public View getCustomMessageView(Fragment fragment, YWMessage msg) {
    String data = "";
    if (msg.getMessageBody().getExtraData() != null) {
        // 这里的ExtraData主要是方便用户在内存中存储数据,这样有些复杂的消息就不需要反复地去解析
        data = (String) msg.getMessageBody().getExtraData();
    } else {
        // 没有解析过,则解析一遍,然后临时存储到Extradata中
        String content = msg.getMessageBody().getContent();
        JSONObject object = JSON.parseObject(content);
        data = object.getString("myData1");
        msg.getMessageBody().setExtraData(data);
    }

    LinearLayout layout = (LinearLayout) View.inflate(
            DemoApplication.getContext(),
            R.layout.demo_custom_tribe_msg_layout, null);
    TextView textView = (TextView) layout.findViewById(R.id.msg_content);
    textView.setText(data);
    return layout;
}
//第三步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class);

聊天界面中自定义消息的点击和长按事件处理

聊天界面中消息自定义点击事件

/**
 * 定制点击消息事件, 每一条消息的点击事件都会回调该方法,开发者根据消息类型,对不同类型的消息设置不同的点击事件
 * @param fragment  聊天窗口fragment对象
 * @param message   被点击的消息
 * @return true:使用用户自定义的消息点击事件,false:使用默认的消息点击事件
 */
@Override
public boolean onMessageClick(Fragment fragment, YWMessage message) {
    Notification.showToastMsg(fragment.getActivity(), "触发了自定义MessageClick事件");
    if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_GEO){
        Notification.showToastMsg(fragment.getActivity(), "你点击了地理位置消息消息");
        return true;
    } else if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_P2P_CUS || message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_TRIBE_CUS){
        Notification.showToastMsg(fragment.getActivity(), "你点击了自定义消息");
        return true;
    }
    return false;
}

聊天界面中消息自定义长按事件

/**
 * 定制长按消息事件,每一条消息的长按事件都会回调该方法,开发者根据消息类型,对不同类型的消息设置不同的长按事件
 * @param fragment  聊天窗口fragment对象
 * @param message   被点击的消息
 * @return true:使用用户自定义的长按消息事件,false:使用默认的长按消息事件
 */
@Override
public boolean onMessageLongClick(final Fragment fragment, final YWMessage message) {
    if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_IMAGE || //自定义图片长按的事件处理,无复制选项。
            message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_GIF
            ) {
        new YWAlertDialog.Builder(fragment.getActivity()).setTitle(getShowName(WXAPI.getInstance().getConversationManager().getConversationByConversationId(message.getConversationId()))).setItems(new String[]{"删除"}, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                WXAPI.getInstance().getConversationManager().getConversationByConversationId(message.getConversationId()).getMessageLoader().deleteMessage(message);
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        }).create().show();
        return true;
    } else if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_AUDIO) {
        String[] items = new String[1];
        if (mUserInCallMode) { //当前为听筒模式
            items[0] = "使用扬声器模式";
        } else { //当前为扬声器模式
            items[0] = "使用听筒模式";
        }
        new YWAlertDialog.Builder(fragment.getActivity()).setTitle(getShowName(WXAPI.getInstance().getConversationManager().getConversationByConversationId(message.getConversationId()))).setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (mUserInCallMode) {
                    mUserInCallMode = false;
                } else {
                    mUserInCallMode = true;
                }
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        }).create().show();
        return true;
    } else if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_GEO){
        Notification.showToastMsg(fragment.getActivity(), "你长按了地理位置消息");
        return true;
    } else if (message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_P2P_CUS || message.getSubType() == YWMessage.SUB_MSG_TYPE.IM_TRIBE_CUS){
        Notification.showToastMsg(fragment.getActivity(), "你长按了自定义消息");
        return true;
    }
    return false;
}

聊天界面中消息点击url的行为的回调

此功能可实现开发者希望自己处理某些URL的点击响应

//如果聊天消息的内容是url.点击url会回调给设置ChattingMsgUrlHandler处理。
ChattingHandlerManager.getInstance().setChattingMsgUrlHandler(new ChattingMsgUrlHandler() {
    @Override
    public boolean onInterceptClick(String url, YWMessage message,Activity chattingContext) {
        Toast.makeText(OpenImUiActivity.this, url+" "+message.getAuthorUserId(), Toast.LENGTH_LONG).show();
        chattingContext.finish();
        return false;
    }
});

聊天界面中消息气泡内容中的数字格式字符串(包括中间有一个空格的相连数字格式字符串)点击回调

此功能允许开发者自定义对数字串的操作,之前版本SDK对疑似号码的数字字符串,点击默认打开拨号界面。

示例代码在ChattingOperationCustomSample.java

/**
     * 数字字符串点击事件
     * @param activity
     * @param clickString 被点击的数字string
     * @return false:不处理
     *         true:需要开发者在return前添加自己实现的响应逻辑代码
     */
    @Override
    public boolean onNumberClick(Activity activity, String clickString) {
        return false;
    }

表情扩展

SDK允许替换SDK默认表情或者新增表情,新增表情包括Emoji表情和图片表情。Emoji表情不是指系统的Emoji表情,而是开发者自定义含义和对应图片的表情,图片表情就是在点击时直接以图片形式发送,不会出现在输入框。

先约定一下几个概念:

  • 1.表情快捷键(shortCuts),用于在协议中传输的表情符号
  • 2.表情含义(meanings),表情中文含义,一般用于显示在通知栏中
  • 3.表情资源ID号(smilyRes),这个好理解,就是Android的资源ID

替换SDK表情

表情初始化相关的方法请在ApplicationOncreate中调用,并在initNotify中进行

YWSmilyMgr.setSmilyInitNotify(new YWSmilyMgr.SmilyInitNotify() {
    @Override
    public void onDefaultSmilyInitOk() {
        //这里进行表情的初始化


        //最后要清空通知,防止memory leak
        YWSmilyMgr.setSmilyInitNotify(null);
    }
});

新增表情

新增图片表情

/**
     * 添加新的表情包,该方法添加的表情是图片类型,开发者无需考虑多端解析问题
     * @param smileyResArray
     *          表情资源数组
     * @param horizontalCount
     *          水平展示个数
     * @param verticalCount
     *          垂直展示个数
     * <br>
     * 注:该方法添加的表情属于自定义Image表情,表情会当做图片发送
     */
    public static void addImageSmiley(int[] smileyResArray, int horizontalCount, int verticalCount) {
        YWIMSmiley smiley = new YWIMSmiley(smileyResArray);
        smiley.setHorizontalCount(horizontalCount);
        smiley.setVerticalCount(verticalCount);
        YWSmilyMgr.addNewSmiley(smiley);
    }

新增Emoji表情

/**
 * 添加新的表情包,该方法会在原有表情包的基础上扩充(没有指定水平和垂直方向上的个数,则使用默认---水平:7 垂直:3)
 * @param smileyResArray
 *      drawable资源id数组
 * @param shortCuts
 *      快捷方式数组
 * @param meanings
 *      含义数组
 * <br>
 * 注:该方法添加的表情属于自定义Emoji表情,填加后的展示需要开发者自己考虑多端解析的实现
 */
public static void addEmojiSmiley(int[] smileyResArray, String[] shortCuts, String[] meanings) {
    YWIMSmiley smiley = new YWIMSmiley(smileyResArray, shortCuts, meanings);
    YWSmilyMgr.addNewSmiley(smiley);
}

/**
 * 添加新的表情包,该方法会在原有表情包的基础上扩充
 * @param smileyResArray
 *      drawable资源id数组
 * @param shortCuts
 *      快捷方式数组
 * @param meanings
 *      含义数组
 * @param horizontalCount
 *      水平方向上的展示个数
 * @param verticalCount
 *      垂直方向上的展示个数
 *
 * <br>
 * 注:该方法添加的表情属于自定义Emoji表情,填加后的展示需要开发者自己考虑多端解析的实现
 */
public static void addEmojiSmiley(int[] smileyResArray, String[] shortCuts, String[] meanings, int verticalCount, int horizontalCount) {
    YWIMSmiley smiley = new YWIMSmiley(smileyResArray, shortCuts, meanings, horizontalCount, verticalCount);
    YWSmilyMgr.addNewSmiley(smiley);
}

**注:表情图标目前默认大小是32*32,单位为dp,如果需要修改请在aliwx_smily_item.xml中修改 **

聊天窗口顶部自定义view

展示自定义view

//打开聊天窗口前调用以下代码
//参数view:自定义view,返回null则不显示自定义view
mIMKit.showCustomView(View view);

隐藏自定义view

mIMKit.hideCustomView(View view);

自定义商品消息view

//第一步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次)
    AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class);

//第二步,继承IMChattingPageOperateion,根据需求覆盖getGoodsInfoFromUrl()或者getCustomUrlView(),具体覆盖方式如下:

返回SDK需要的商品信息内容,展示为SDK默认的商品消息view

/**
 * 获取url对应的商品详情信息,当openIM发送或者接收到url消息时会首先调用getCustomUrlView(Fragment, YWMessage, String, YWConversation),若getCustomUrlView()返回null,才会回调用该方法获取商品详情,若getCustomUrlView()返回非null的view对象,则直接用此view展示url消息,不再回调该方法。因此,如果希望该方法被调用,请确保getCustomUrlView(Fragment, YWMessage, String, YWConversation)返回null。
 * @param fragment  可以通过 fragment.getActivity拿到Context
 * @param message   url所属的message
 * @param url       url
 * @param ywConversation message所属的conversion
 * @return  商品信息
 */
@Override
public GoodsInfo getGoodsInfoFromUrl(Fragment fragment, YWMessage message, String url, YWConversation ywConversation) {
    if (url.equals("https://www.taobao.com/ ")) {
        Bitmap bitmap = BitmapFactory.decodeResource(fragment.getResources(), R.drawable.pic_1_18);
        //GoodsInfo的四个参数分别为:宝贝名称,当前价格,原始价格,运费,商品图片;
        GoodsInfo info = new GoodsInfo("我的淘宝宝贝", "60.03", "86.25", "8.00", bitmap);
        return info;
    }
    return null;
}

根据商品url自定义商品消息view

/**
 * 获取url对应的自定义view,当openIM发送或者接收到url消息时会回调该方法获取该url的自定义view。若开发者实现了该方法并且返回了一个view对象,openIM将会使用该view展示对应的url消息。
 * @param fragment  可以通过 fragment.getActivity拿到Context
 * @param message   url所属的message
 * @param url       url
 * @param ywConversation message所属的conversion
 * @return  自定义Url view
 */
@Override
public View getCustomUrlView(Fragment fragment, YWMessage message, String url, YWConversation ywConversation) {
    if (url.equals("https://www.baidu.com/ ")) {
        LinearLayout layout = (LinearLayout) View.inflate(
                DemoApplication.getContext(),
                R.layout.demo_custom_tribe_msg_layout, null);
        TextView textView = (TextView) layout.findViewById(R.id.msg_content);
        textView.setText("I'm from getCustomUrlView!");
        return layout;
    }
    return null;
}

自定义文本消息文字颜色

/**
 * 获取文本消息中的文字颜色,该接口可以设置文本、链接和数字的颜色
 * @param conversation 当前会话
 * @param isSelf       是否是自己发送的消息,true:自己发送的消息,false:别人发送的消息
 * @param type         文本类型,1:普通文本,2:链接,3:数字
 * @return 颜色资源Id
 */
@Override
public int getCustomTextColor(YWConversation conversation, boolean isSelf, int type) {
    if (type == 1){
        //普通文字颜色
    } else if (type == 2){
        //超链接颜色
    } else if (type == 3){
        //数字颜色
    }
    return super.getCustomTextColor(conversation, isSelf, type);
}

自定义会话列表和聊天窗口dimens

拷贝OneSDK工程中的res/values/custom_values.xml文件到你的主工程的res/values目录下,然后根据需求修改你的主工程中的custom_values.xml文件中的对应变量即可。

聊天窗口操作对象获取

/**
 * 聊天窗口初始化完成,开发者可以使用 {@link IMChattingBizService}接口来进行获取聊天窗口更多的对象
 * @param bizService
 */
void onInitFinished(IMChattingBizService bizService);


/**
 * 提供给开发者可以主动调用的一些方法集合,来操作聊天窗口
 */
public interface IMChattingBizService {
    /**
     * 获取聊天窗口输入框
     * @return
     * @deprecated 该方法已废弃, 后续请使用{@link IYWChattingReplyBar#getInputEditTextView()}
     */
    EditText getInputEditTextView();

    /**
     * 获取聊天窗口对应的会话
     * @return
     */
    YWConversation getConversation();

    /**
     * 获取Fragment
     * @return
     */
    Fragment getFragment();

    /**
     * 获取聊天窗口回复框
     * @return
     */
    IYWChattingReplyBar getChattingReplyBar();

    /**
     * 获取当前聊天窗口对应的YWIMKit对象
     * @return
     */
    YWIMKit getIMKit();

    /**
     * 停止播放语音消息
     */
    void stopAudio();
}

/**
 * 开发者主动操作聊天窗口回复框
 */
public interface IYWChattingReplyBar {

    /**
     * 设置回复框的背景色
     * @param colorId
     */
    void setBackgroundColor(int colorId);

    /**
     * 获取回复框中的输入框
     * @return
     */
    EditText getInputEditTextView();

    /**
     * 设置回复框的输入框内右侧drawable和对应的点击事件
     * @param drawable  输入框内右侧drawable
     * @param listener  右侧drawable的点击事件
     */
    void setInputEditTextRightDrawable(Drawable drawable, OnEditTextDrawableClickListener listener);

    /**
     * 展示回复框下方区域,即表情区域
     * @param fragment 需要展示的fragment
     * @param height   fragment高度, 如果开发者不想控制高度请传
     */
    void showReplyFragment(Fragment fragment, int height);

    /**
     * 隐藏回复框下方区域,即表情区域
     */
    void hideReplyFragment();

    /**
     * 显示软键盘
     */
    void showKeyboard();

    /**
     * 隐藏软键盘
     */
    void hideKeyBoard();

    /**
     * 显示录音按钮
     */
    void showRecordWindow();

    /**
     * 隐藏录音按钮
     */
    void hideRecordWindow();
}

设置语音播放动画UI

/**
 * 设置声音播放ImageView
 * @param view
 * @param index 0,1,2,3,分别表示动画第一帧,第二帧,第三帧,及静态的图片
 * @param direction 0,自己,1,对方
 */
@Override
public void onSetAudioContentImage(ImageView view, int index, int direction){
    //这里对view进行图片的设置
}

语音消息录制按钮自定义

/**
 * 自绘录制按钮
 * @param canvas
 * @param button
 */
void onCustomDrawRecordButton(Canvas canvas, RecordButton button);

聊天底部工具栏扩展

允许自定义插件item位置,添加新的item,修改原有item,设置是否隐藏,设置点击事件

/**
 *
 * 用于增加聊天窗口 下方回复栏的操作区的item
 *
 * ReplyBarItem:
 * itemId:唯一标识 建议从1开始
 * ItemImageRes:显示的图片
 * ItemLabel:文字
 * needHide:是否隐藏 默认: false ,  显示:false , 隐藏:true
 * OnClickListener: 自定义点击事件, null则使用默认的点击事件
 * 参照示例返回List<ReplyBarItem>用于操作区显示item列表,可以自定义顺序和添加item
 *
 * @param pointcut         聊天窗口fragment
 * @param conversation 当前会话,通过conversation.getConversationType() 区分个人单聊,与群聊天
 * @param replyBarItemList 默认的replyBarItemList,如拍照、选择照片、短视频等
 * @return
 */
@Override
public List<ReplyBarItem> getCustomReplyBarItemList(final Fragment pointcut,final YWConversation conversation, List<ReplyBarItem> replyBarItemList)

replyBarItemList会包含默认的ReplyBarItem,如拍照、选择照片、短视频等,开发者使用可以新建自己的replyBarItemList,将原replyBarItemList中的item根据自己想要的次序放入,也可以添加自己的item,也可以设置拍照、选择照片、短视频等默认item的显示隐藏和点击事件。具体示例请参考:

openIMDemo/src/com/taobao/openimui/sample/ChattingOperationCustomSample.java
可设置点 设置方式
设置唯一ID 请设置ReplyBarItem的itemId,注意根据注释不要和默认Item的ID重合(具体ID请查看YWChattingPlugin.ReplyBarItem中的数值)
设置文字 请设置ReplyBarItem的ItemLabel
设置图标 请设置ReplyBarItem的ItemImageRes
设置隐藏 请设置ReplyBarItem的needHide为true,默认值为false不隐藏
设置自定义点击事件 请设置ReplyBarItem的OnClickListener,默认值null使用默认点击事件。item的点击事件通常要startActivityForResult结合onActivityResult一起使用,开发者可以灵活使用requestcode和setData(intent)做数据传递。

自定义拍照和选择照片

首先设置自定义拍照或选择照片replyBarItem的点击事件,然后startActivityForResult启动自己的拍照或选择照片activity。请参照如下要求发送照片.
在startActivityForResult[包含欲发送图片的Activity]时,requestcode请传YWImageHandler.YWImageSender.YW_REQUESTCODE_MULIT_PIC_WITH_DATA。在finish时需要在intent中放入发送图片所需的信息,参照下面示例:

Intent intent = new Intent();
ArrayList<String> selectedList = new ArrayList<String>();
selectedList.add(oriImageUrl);

// selectedList:欲发送的图片本地路径list,类型ArrayList<String>
intent.putStringArrayListExtra(YWImageHandler.YWImageSender.YW_RESULT_LIST, selectedList);

// compress : 是否适当压缩图片,类型boolean
intent.putExtra(YWImageHandler.YWImageSender.YW_NEED_COMPRESS,compress);
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();

这样,当退回聊天窗口时,就会发送出图片了.

打开聊天窗口自动发送一条消息,支持本地隐藏

打开聊天窗口自动发送一条消息给对方。需要注意的是,仅支持本地隐藏。当用户切换手机或清楚数据后,会漫游消息下这些消息并出现在用户的聊天界面上!需要覆写IMChattingPageOperateion中下面的API

@Override
public YWMessage ywMessageToSendWhenOpenChatting(Fragment fragment, YWConversation conversation, boolean isConversationFirstCreated) {
    return null;
}

示例代码如下,可参考ChattingOperationCustomSample:

/**
 * 当打开聊天窗口时,自动发送该消息给对方
 * @param fragment      聊天窗口fragment
 * @param conversation  当前会话
 * @param isConversationFirstCreated  是否是首次创建会话
 * @return 自动发送的消息(注意,内容empty则不自动发送)
 */
@Override
public YWMessage ywMessageToSendWhenOpenChatting(Fragment fragment, YWConversation conversation, boolean isConversationFirstCreated) {
    //与客服的会话
    if(conversation.getConversationId().contains("openim官方客服")){
            final SharedPreferences defalultSprefs = fragment.getActivity().getSharedPreferences(
                "ywPrefsTools", Context.MODE_PRIVATE);
            long lastSendTime = defalultSprefs.getLong("lastSendTime_"+conversation.getConversationId(), -1);
            //24小时后再次发送本地隐藏消息
            if(System.currentTimeMillis()-lastSendTime>24*60*60*1000){
                YWMessage textMessage = YWMessageChannel.createTextMessage("你好");
                //添加发送的消息不显示在对方界面上的本地标记
                textMessage.setLocallyHideMessage(true);
                //保存发送时间戳
                SharedPreferences.Editor edit = defalultSprefs.edit();
                edit.putLong("lastSendTime_"+conversation.getConversationId(),System.currentTimeMillis());
                edit.commit();
                return textMessage;
            }
    }
    //返回null,则不发送
    return null;

}

自定义时间文案

需要覆写IMChattingPageOperateion中下面的API

/**
 * @param fragment     聊天窗口fragment
 * @param conversation 当前聊天窗口对应的会话
 * @param time         默认时间文案
 * @return  如果是NULL,则不显示,如果是空字符串,则使用SDK默认的文案,如果返回非空串,则使用用户自定义的
 */
@Override
public String getCustomTimeString(Fragment fragment, YWConversation conversation, String time) {
    return "";
}

FAQ

关于此文档暂时还没有FAQ
返回
顶部