logo
In-app Chat
SDK Error Codes
On this page

Render Conversation Messages on the Chat Page


Overview

This article describes how to use the ZIM SDK to render conversation messages on a basic one-on-one chat page.

showMessage.png

Prerequisites

You have already integrated the ZIM SDK into your project and implemented basic message sending and receiving. For details, refer to Quick Start - Implement Basic Message Sending and Receiving.

Message Data Source Overview

The message data sources that need to be rendered on the page mainly include the following:

  1. Historical conversation messages: When you first enter the chat page and view historical messages, you need to query historical conversation messages and render them to the chat interface.
  2. Real-time received messages: Real-time received chat messages need to be rendered to the chat interface.
  3. Local sent messages: Local sent chat messages (including sending, sending successfully, and sending failed statuses) need to be rendered to the chat interface.

Get Message Data and Render to the Chat Interface

As an example of a single chat conversation, when you navigate to the chat page, you need to save the corresponding single chat conversationID (the userID of the other party) and maintain a message list myMessageList for saving the current conversation.

Before obtaining message data, you also need to implement an addMessage utility method to merge message data.

public void addMessage(List<ZIMMessage> addList) {
    if (addList == null || addList.isEmpty()) return;

    List<ZIMMessage> mutableList = new ArrayList<>();
    if (myMessageList != null) {
        mutableList.addAll(myMessageList);
    }

    for (ZIMMessage newMsg : addList) {
        boolean replaced = false;
        for (int i = 0; i < mutableList.size(); i++) {
            ZIMMessage oldMsg = mutableList.get(i);
            if ((newMsg.getMessageID() != null && newMsg.getMessageID().equals(oldMsg.getMessageID())) ||
                (newMsg.getLocalMessageID() != null && newMsg.getLocalMessageID().equals(oldMsg.getLocalMessageID()))) {
                mutableList.set(i, newMsg);
                replaced = true;
                break;
            }
        }
        if (!replaced) {
            mutableList.add(newMsg);
        }
    }

    mutableList.sort(Comparator.comparingLong(ZIMMessage::getOrderKey));
    myMessageList = mutableList;
}
Note

Each time you call a message-related interface (such as the interfaces shown below), you will get a message list ZIMMessage[]. The obtained message list needs to be merged to obtain a message list without duplicate messages and ordered messages for rendering on the message page. The message sorting rule is to sort by the orderkey property in ZIMMessage (the larger the orderkey, the newer the current message); the de-duplication rule is to determine whether the message object is the same message based on the localMessageID of the message, and replace the new data with the old data when it is duplicated.

Query Historical Messages and Render Them to the Chat Interface

Call the queryHistoryMessage interface to query historical messages from new to old (from the most recent message to the oldest message in chronological order) and render them to the chat interface.


ZIMMessageQueryConfig queryConfig = new ZIMMessageQueryConfig();
queryConfig.count = 20;
queryConfig.nextMessage = null; // When the first query is empty, the earliest message is passed in when more historical messages are needed

zim.queryHistoryMessage(
        myConversationID,
        ZIMConversationType.PEER,
        queryConfig,
        (conversationID, conversationType, messageList, errorInfo) -> {
            addMessage(messageList);
            // update UI
        });

Get Real-time Received Messages and Render Them to the Chat Interface

Listen to the onPeerMessageReceived interface to get real-time received messages and render them to the chat interface.

 public void onPeerMessageReceived(ZIM zim, List<ZIMMessage> messageList, 
                                  ZIMMessageReceivedInfo info, String fromUserID) {
    // Only process messages from the current conversation
    if (!fromUserID.equals(myConversationID)) {
        return; // Messages from non-current conversations are ignored
    }

    // Merge messages into message list
    addMessage(messageList);

    // Update UI, such as refreshing RecyclerView
    runOnUiThread(() -> {
        myAdapter.notifyDataSetChanged();
        if (!myMessageList.isEmpty()) {
            recyclerView.scrollToPosition(myMessageList.size() - 1);
        }
    });
}

Render Local Sent Messages to the Chat Interface

Listen to the onMessageSentStatusChanged interface to get the change of the sending status of the local sent message (sending, sending successfully, and sending failed), and render the local sent message and its sending status to the chat interface.


@Override
public void onMessageSentStatusChanged(List<ZIMMessageSentStatusChangeInfo> messageSentStatusChangeInfoList) {
    for (ZIMMessageSentStatusChangeInfo info : messageSentStatusChangeInfoList) {
        if (!info.getMessage().getConversationID().equals(myConversationID)) {
            continue;
        }
        addMessage(Collections.singletonList(info.getMessage()));
    }
    // Update UI
    runOnUiThread(() -> {
        myAdapter.notifyDataSetChanged();
        if (!myMessageList.isEmpty()) {
            recyclerView.scrollToPosition(myMessageList.size() - 1);
        }
    });
}

By following the above steps, you can render historical messages, real-time received messages, and local sent messages (including sending status) in the chat page.

Previous

Modify a notification badge

Next

Subscribe to user online status