300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 融云即时通讯SDK集成 -- 定制UI(二) ——添加自定义表情库

融云即时通讯SDK集成 -- 定制UI(二) ——添加自定义表情库

时间:2021-02-04 02:03:24

相关推荐

融云即时通讯SDK集成 -- 定制UI(二) ——添加自定义表情库

背景:

最近公司新上的app要加上即时通讯的功能, 自己快速实现一个当然是不可能的了(项目deadline也顶不住哇).就从各家成熟的SDK厂商选来选去的, 各有各的好也各有各的不足.最后点兵点将,选了融云家的SDK(老板说了算hhhh).

他家的官网和文档地址:

官网:/

文档:/v4

这个任务当然还是落在我的头上. 我是使用的他们家的带UI的sdk,(他们家有带UI和不带UI的两种sdk, 不带UI的sdk就是只有即时通讯能力, 所有的UI都需要开发者自定实现, 带UI的sdk封装了一些基本的界面,例如会话列表, 和别人聊天的会话界面.)当然这些已经集成了UI的sdk并不能完全满足一个产品的需求, 所以这篇文章跟大家讲下如何添加一套自定义的表情包.

效果如下哈:

虽然这里有点难看了哈哈, 不过是为了给大家展示方法嘛, 就不管那么多了. 可以看到底下除了默认的emoji的表情包, 还多了一个tab, 我是从QQ表情搞了一套, 直接就加在这里了. 一个可爱的小猪猪🐷哈哈哈.

添加步骤

需要改动的有这么几个类:

AndroidEmoji: 控制emoji图标资源, 编码, 以及相应展示的类

RongExtension: 会话界面除去聊天气泡与title bar的整个下方输入区域

IEmoticonTab: 表情tab

DefaultExtensionModule: 表情tab的上层控件.

对于AndroidEmoji这个类, 可以直接照抄, 把资源文件替换成自己准备好的图标, 以及编码/描述

public class ConversationListAdapter extends BaseAdapter<UIConversation> {private final static String TAG = "ConversationListAdapter";LayoutInflater mInflater;Context mContext;@Overridepublic long getItemId(int position) {UIConversation conversation = getItem(position);if (conversation == null)return 0;return conversation.hashCode();}protected class ViewHolder {public View layout;public View leftImageLayout;public View rightImageLayout;public View leftUnReadView;public View rightUnReadView;public AsyncImageView leftImageView;public TextView unReadMsgCount;public ImageView unReadMsgCountIcon;public AsyncImageView rightImageView;public TextView unReadMsgCountRight;public ImageView unReadMsgCountRightIcon;public ProviderContainerView contentView;}public ConversationListAdapter(Context context) {super();mContext = context;mInflater = LayoutInflater.from(mContext);}public int findGatheredItem(Conversation.ConversationType type) {int index = getCount();int position = -1;while ((index-- > 0)) {UIConversation uiConversation = getItem(index);if (uiConversation.getConversationType().equals(type)) {position = index;break;}}return position;}public int findPosition(Conversation.ConversationType type, String targetId) {int index = getCount();int position = -1;while (index-- > 0) {if (getItem(index).getConversationType().equals(type)&& getItem(index).getConversationTargetId().equals(targetId)) {position = index;break;}}return position;}@Overrideprotected View newView(Context context, int position, ViewGroup group) {View result = mInflater.inflate(R.layout.rc_item_conversation, null);ViewHolder holder = new ViewHolder();holder.layout = findViewById(result, R.id.rc_item_conversation);holder.leftImageLayout = findViewById(result, R.id.rc_item1);holder.rightImageLayout = findViewById(result, R.id.rc_item2);holder.leftUnReadView = findViewById(result, R.id.rc_unread_view_left);holder.rightUnReadView = findViewById(result, R.id.rc_unread_view_right);holder.leftImageView = findViewById(result, R.id.rc_left);holder.rightImageView = findViewById(result, R.id.rc_right);holder.contentView = findViewById(result, R.id.rc_content);holder.unReadMsgCount = findViewById(result, R.id.rc_unread_message);holder.unReadMsgCountRight = findViewById(result, R.id.rc_unread_message_right);holder.unReadMsgCountIcon = findViewById(result, R.id.rc_unread_message_icon);holder.unReadMsgCountRightIcon = findViewById(result, R.id.rc_unread_message_icon_right);result.setTag(holder);return result;}@Overrideprotected void bindView(View v, int position, final UIConversation data) {ViewHolder holder = (ViewHolder) v.getTag();if (data == null) {return;}/*通过会话类型,获得对应的会话provider.ex: PrivateConversationProvider*/IContainerItemProvider provider = RongContext.getInstance().getConversationTemplate(data.getConversationType().getName());if (provider == null) {RLog.e(TAG, "provider is null");return;}View view = holder.contentView.inflate(provider);provider.bindView(view, position, data);//设置背景色if (data.isTop())holder.layout.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.rc_item_top_list_selector));elseholder.layout.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.rc_item_list_selector));ConversationProviderTag tag = RongContext.getInstance().getConversationProviderTag(data.getConversationType().getName());int defaultId;if (data.getConversationType().equals(Conversation.ConversationType.GROUP)) {defaultId = R.drawable.rc_default_group_portrait;} else if (data.getConversationType().equals(Conversation.ConversationType.DISCUSSION)) {defaultId = R.drawable.rc_default_discussion_portrait;} else {defaultId = R.drawable.rc_default_portrait;}// 1:图像靠左显示。2:图像靠右显示。3:不显示图像。if (tag.portraitPosition() == 1) {holder.leftImageLayout.setVisibility(View.VISIBLE);holder.leftImageLayout.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mOnPortraitItemClick != null)mOnPortraitItemClick.onPortraitItemClick(v, data);}});holder.leftImageLayout.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {if (mOnPortraitItemClick != null)mOnPortraitItemClick.onPortraitItemLongClick(v, data);return true;}});if (data.getConversationGatherState()) {holder.leftImageView.setAvatar(null, defaultId);} else {if (data.getIconUrl() != null) {holder.leftImageView.setAvatar(data.getIconUrl().toString(), defaultId);} else {holder.leftImageView.setAvatar(null, defaultId);}}if (data.getUnReadMessageCount() > 0) {holder.unReadMsgCountIcon.setVisibility(View.VISIBLE);setUnReadViewLayoutParams(holder.leftUnReadView, data.getUnReadType());if (data.getUnReadType().equals(UIConversation.UnreadRemindType.REMIND_WITH_COUNTING)) {if (data.getUnReadMessageCount() > 99) {holder.unReadMsgCount.setText(mContext.getResources().getString(R.string.rc_message_unread_count));} else {holder.unReadMsgCount.setText(Integer.toString(data.getUnReadMessageCount()));}holder.unReadMsgCount.setVisibility(View.VISIBLE);holder.unReadMsgCountIcon.setImageResource(R.drawable.rc_unread_count_bg);} else {holder.unReadMsgCount.setVisibility(View.GONE);holder.unReadMsgCountIcon.setImageResource(R.drawable.rc_unread_remind_list_count);}} else {holder.unReadMsgCountIcon.setVisibility(View.GONE);holder.unReadMsgCount.setVisibility(View.GONE);}holder.rightImageLayout.setVisibility(View.GONE);} else if (tag.portraitPosition() == 2) {holder.rightImageLayout.setVisibility(View.VISIBLE);holder.rightImageLayout.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mOnPortraitItemClick != null)mOnPortraitItemClick.onPortraitItemClick(v, data);}});holder.rightImageLayout.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {if (mOnPortraitItemClick != null)mOnPortraitItemClick.onPortraitItemLongClick(v, data);return true;}});if (data.getConversationGatherState()) {holder.rightImageView.setAvatar(null, defaultId);} else {if (data.getIconUrl() != null) {holder.rightImageView.setAvatar(data.getIconUrl().toString(), defaultId);} else {holder.rightImageView.setAvatar(null, defaultId);}}if (data.getUnReadMessageCount() > 0) {holder.unReadMsgCountRightIcon.setVisibility(View.VISIBLE);setUnReadViewLayoutParams(holder.rightUnReadView, data.getUnReadType());if (data.getUnReadType().equals(UIConversation.UnreadRemindType.REMIND_WITH_COUNTING)) {holder.unReadMsgCount.setVisibility(View.VISIBLE);if (data.getUnReadMessageCount() > 99) {holder.unReadMsgCountRight.setText(mContext.getResources().getString(R.string.rc_message_unread_count));} else {holder.unReadMsgCountRight.setText(Integer.toString(data.getUnReadMessageCount()));}holder.unReadMsgCountRightIcon.setImageResource(R.drawable.rc_unread_count_bg);} else {holder.unReadMsgCount.setVisibility(View.GONE);holder.unReadMsgCountRightIcon.setImageResource(R.drawable.rc_unread_remind_without_count);}} else {holder.unReadMsgCountIcon.setVisibility(View.GONE);holder.unReadMsgCount.setVisibility(View.GONE);}holder.leftImageLayout.setVisibility(View.GONE);} else if (tag.portraitPosition() == 3) {holder.rightImageLayout.setVisibility(View.GONE);holder.leftImageLayout.setVisibility(View.GONE);} else {throw new IllegalArgumentException("the portrait position is wrong!");}MessageContent content = data.getMessageContent();if (content != null && content.isDestruct()) {RongIMClient.getInstance().getMessage(data.getLatestMessageId(), new RongIMClient.ResultCallback<Message>() {@Overridepublic void onSuccess(Message message) {if (message == null) {EventBus.getDefault().post(new Event.MessageDeleteEvent(data.getLatestMessageId()));}}@Overridepublic void onError(RongIMClient.ErrorCode e) {}});}}protected void setUnReadViewLayoutParams(View view, UIConversation.UnreadRemindType type) {ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();Context context = view.getContext();if (type == UIConversation.UnreadRemindType.REMIND_WITH_COUNTING) {params.width = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_18);params.height = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_18);params.leftMargin = (int) mContext.getResources().getDimension(R.dimen.rc_dimen_size_44);params.topMargin = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_5);} else {params.width = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_9);params.height = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_9);params.leftMargin = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_50);params.topMargin = (int) context.getResources().getDimension(R.dimen.rc_dimen_size_7);}view.setLayoutParams(params);}private OnPortraitItemClick mOnPortraitItemClick;public interface OnPortraitItemClick {void onPortraitItemClick(View v, UIConversation data);boolean onPortraitItemLongClick(View v, UIConversation data);}public void setOnPortraitItemClick(OnPortraitItemClick onPortraitItemClick) {this.mOnPortraitItemClick = onPortraitItemClick;}}

集成DefaultExtensionModule, 实现MyExtensionModule, 重写getEmoticonTabs()方法, 为每个图标设置监听.

@Overridepublic List<IEmoticonTab> getEmoticonTabs() {List<IEmoticonTab> emoticonTabs = super.getEmoticonTabs();MyEmoticonTab myEmoticonTab =new MyEmoticonTab();myEmoticonTab.setOnItemClickListener(new IEmojiItemClickListener() {@Overridepublic void onEmojiClick(String emoji) {EditText editText = MyExtensionModule.this.mEditText;if (editText != null) {int start = editText.getSelectionStart();editText.getText().insert(start, emoji);}}@Overridepublic void onDeleteClick() {EditText editText = MyExtensionModule.this.mEditText;if (editText != null) {editText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));}}});emoticonTabs.add(myEmoticonTab);return emoticonTabs;}

继承RongExtension, 实现MyRongExtension, 然后获取到editText, 为其设置监听, 代码如下:

public class MyRongExtension extends RongExtension {EditText mEditText;public MyRongExtension(Context context) {super(context);tryAddTextChangedAction();}public MyRongExtension(Context context, AttributeSet attrs) {super(context, attrs);tryAddTextChangedAction();}private void tryAddTextChangedAction() {mEditText = getInputEditText();TextWatcher textWatcher = new TextWatcher() {private int start;private int count;@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {this.start = start;this.count = count;}@Overridepublic void afterTextChanged(Editable s) {// 这块的检验规则是纯emoji的, 加其他表情的话直接给他去掉, 或者自己写规则。//if (QQEmoji.isQQEmoji(s.subSequence(start, start + count).toString())) {mEditText.removeTextChangedListener(this);String resultStr = QQEmoji.replaceEmojiWithText(s.toString());mEditText.setText(QQEmoji.ensure(resultStr), TextView.BufferType.SPANNABLE);mEditText.setSelection(mEditText.getText().length());mEditText.addTextChangedListener(this);//}}};mEditText.addTextChangedListener(textWatcher);}}

这样一来, 就大功告成啦. 添加好了一套属于自己的表情包!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。