位置 | 定制点 | 定制方式 |
---|---|---|
顶部标题栏 | 整个标题栏(支持隐藏) | 实现接口 |
消息气泡 | 文本消息和语音消息 | 实现接口 |
消息中URL | URL点击事件 | 实现接口 |
消息中数字字符串 | 点击事件 | 实现接口 |
底部消息栏“+” | +”内增加选项 | 实现接口 |
自定义消息 | 展示、点击和长按事件 | 实现接口 |
地理位置消息 | 消息展示、点击和长按事件 | 实现接口 |
语音消息播放 | 使用听筒或者扬声器模式播放语音消息 | 实现接口 |
自定义消息展示 | 不包含头像的自定义消息展示 | 实现接口 |
背景 | 背景颜色或图片 | 实现接口 |
聊天界面头像样式 | 圆角正方形、直角正方形、圆形 | 实现接口 |
聊天底部工具栏(ChattingReplyBar) | 允许自定义高度,隐藏语音表情发送按钮 | 实现接口 |
聊天底部工具栏扩展(ChattingReplyBar) | 允许自定义插件item位置,添加新的item,修改原有item,设置是否隐藏,设置点击事件 | 实现接口 |
表情扩展 | 可以添加自定义Emoji表情或者图片表情 | 方法调用 |
默认头像修改 | 默认头像图片 | 实现接口 |
聊天窗口顶部 | 聊天窗口顶部悬浮自定义view | 实现接口 |
商品消息 | 自定义商品消息展示样式 | 实现接口 |
文本消息文字颜色 | 自定义文本消息的文字颜色 | 实现接口 |
会话列表和聊天窗口dimens | 自定义会话列表和聊天窗口部分dimens | 修改资源文件 |
打开聊天窗口 | 打开聊天窗口自动发送一条消息,支持本地隐藏 | 实现接口 |
消息时间 | 自定义时间文案 | 实现接口 |
聊天窗口:IMChattingPageUI, IMChattingPageOperateion
具体请参考工程NotificationInitSampleHelper
//设置消息的聊天气泡背景处理器,可以自定义设置文本以及图片消息的背景图,详细参见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的接口,其它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上的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的点击响应,比如用内部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会回调给设置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表情,而是开发者自定义含义和对应图片的表情,图片表情就是在点击时直接以图片形式发送,不会出现在输入框。
先约定一下几个概念:
表情初始化相关的方法请在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); }
/** * 添加新的表情包,该方法会在原有表情包的基础上扩充(没有指定水平和垂直方向上的个数,则使用默认---水平: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,返回null则不显示自定义view mIMKit.showCustomView(View view);
mIMKit.hideCustomView(View view);
//第一步:在Applicatoin类里将这个自定义接口绑定到单聊界面,加入以下代码(对于单聊界面的所有自定义UI定制只需要加一次) AdviceBinder.bindAdvice(PointCutEnum.CHATTING_FRAGMENT_OPERATION_POINTCUT,ChattingOperationCustomSample.class); //第二步,继承IMChattingPageOperateion,根据需求覆盖getGoodsInfoFromUrl()或者getCustomUrlView(),具体覆盖方式如下:
/** * 获取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,当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); }
拷贝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(); }
/** * 设置声音播放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 ""; }