消息撤回重新编辑

消息撤回后如何实现重新编辑?
发布时间: 2019-08-20 14:51

回答:

消息撤回重新编辑

原有消息撤回逻辑

当执行消息撤回时,SDK 会向对端(对方客户端)发送撤回消息的命令消息,对端收到该命令消息时,会替换要被撤回的消息内容为提示消息内容(xxx 撤回了一条消息),本端(发送客户端)在撤回消息执行成功时会将要被撤回的消息内容进行替换为提示消息内容(你撤回了一条消息),UI 层会收到相应事件并进行更新

添加重新编辑实现

继承 ConversationFragment,重写 public void onEventMainThread(Event.MessageRecallEvent event),该方法会在消息撤回成功时被调用,用来更新 UI。重新实现中,先判断被撤回的消息是否为文本消息,如果是文本消息,将文本内容暂存在 Message 的 extra 字段中,然后调用父类默认实现,代码片段:

public void onEventMainThread(Event.MessageRecallEvent event) {
    if (event.isRecallSuccess()) {
        MessageListAdapter listAdapter = getMessageAdapter();
        int position = listAdapter.findPosition(event.getMessageId());
        if (position != -1) {
            UIMessage uiMessage = listAdapter.getItem(position);
            MessageContent messageContent = uiMessage.getContent();
            if (messageContent instanceof  TextMessage) {
                String content = ((TextMessage) messageContent).getContent();
                uiMessage.setExtra(content);
            }
        }
    }
    super.onEventMainThread(event);
}

继承 RecallMessageItemProvider,重新实现 newView、bindView;在 bindView 方法中,判断 Message 的 extra 字段是否有值,如果有的话就添加“重新编辑”操作;当点击重新编辑时,发出事件,在继承 ConversationFragment 中,实现对应的事件处理,代码片段:

String msgText = message.getExtra();
SpannableStringBuilder ssb = new SpannableStringBuilder(information);
if (!TextUtils.isEmpty(msgText)) {
    String reedit = "重新编辑";
    ssb.append(" ").append(reedit);
    ssb.setSpan(new ReeditClickableSpan(msgText),
            ssb.length() - reedit.length(), ssb.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
viewHolder.contentTextView.setText(ssb);
private class ReeditClickableSpan extends ClickableSpan {

    private String msgText;

    ReeditClickableSpan(String msgText) {
        this.msgText = msgText;
    }

    @Override
    public void onClick(@NonNull View widget) {
        EventBus.getDefault().post(new ReeditEvent(msgText));
    }
}
public void onEventMainThread(EditableRecallMessageItemProvider.ReeditEvent event) {
    rongExtension.getInputEditText().append(event.getMsgText());
}

注:

  • 继承 RecallMessageItemProvider 并实现相应方法后要在 SDK 初始化后进行注册:RongIM.registerMessageTemplate(new EditableRecallMessageItemProvider())

  • 继承 ConversationFragment 时,在 onCreateView 方法中获取 rongExtension:rongExtension = (RongExtension) v.findViewById(io.rong.imkit.R.id.rc_extension);

EditableRecallMessageItemProvider.java.zip