Press enter to see results or esc to cancel.

Android-chat-tutorial

Android Chat Tutorial: Building a Messaging UI

Despite their growing prevalence, chat and messaging apps continue to be tedious to implement. Official documentation is non-existent, while unofficial tutorials are scarce and generally outdated.

 

Google Allo's Android chat UI

 

Colorful chat bubbles filled with text, images, even playable media–how do they do it? The answer is surprisingly simple: RecyclerViews, coupled with the ViewHolder pattern.

This tutorial walks you through the steps required to build a quality messaging UI.

 

Setting up the Activity

In this tutorial, we’ll create a dedicated activity to host our messages. Let’s call it MessageListActivity. The primary component in this activity is a RecyclerView that fills most of the screen. To keep ahead of the curve, a ConstraintLayout will be used as the root ViewGroup.

In addition to displaying message history, chat UIs typically allow the user to send messages through a chatbox. We’ll position this chatbox at the bottom of the screen using constraints. This will anchor it to the soft input keyboard that pops up when the user types.

 

/layout/activity_message_list.xml

This creates two elements:

  1.  A flexible chatbox that expands according to the length of the message being typed
  2.  A RecyclerView that designates the remaining space to past messages

It will look like the following image:

 

layout 1

 

Creating a list item for each message

Use a separate XML file to define the layout of each item (i.e. message) for ListViews and RecyclerViews. It is common practice for each message to contain the sender’s name, their profile image, and a timestamp.

 

Screen Shot 2017-04-04 at 5.09.24 PM

 

Since the chat bubble’s alignment typically indicates the message’s owner, it could be redundant to display the sender’s profile image and name for every message. In the above image, for example, the right-aligned chat bubble indicates that it belongs to the sender, so we need not include the image or name. Most chat clients choose to discard these components altogether. We will do the same by creating two different ViewHolder‘s:

  1. SentMessageHolder for messages that “I” have sent
  2. ReceivedMessageHolder for messages sent by others

To create the above image, we must first create a chat bubble in an XML file. Once again, this is surprisingly simple:

  1. Set a rounded rectangle as the background for TextView
  2. Adjust the paddings
  3. Align the text

/drawable/rounded_rectangle_orange.xml

Voila! We now have a handsome chat bubble housing the message.

 

Screen Shot 2017-04-04 at 5.19.36 PM

 

You can appropriately position the other TextViews using constraints. Be sure to create two more constraints before moving on:

  1. Be sure to set your root layout’s height to wrap_content, so it can accommodate messages containing a single line and messages containing more than a single line
  2. Set the message body’s max_width to an appropriate threshold. Without this constraint, the chat bubble will fill the entire screen’s width, and will look clumsy.

Now let’s apply this model to both the received and sent messages.

 

Received Messages

/layout/item_message_received.xml

This produces the following image for received messages.

 

Screen Shot 2017-04-04 at 5.25.31 PM

 

Sent Messages

For sent messages, align the chat bubble to the right, and remove the sender’s name and profile image.

/layout/item_message_sent.xml

 

Creating an Adapter for the RecyclerView

Populate the RecyclerView with the above XML items by creating an adapter that extends RecyclerView.Adapter. This adapter will accomplish three things:

  1. Store a list of messages
  2. Determine whether a message is sent or received
  3. Inflate the appropriate layout within RecyclerView.

But before venturing any further, we need a list of messages!

Engineering a backend for real-time messaging is, however, beyond the scope of this tutorial. We’ll therefore proceed with the models in SendBird’s chat SDK. It roughly assumes the following structure:

Generic Message and User models

Since it is common to design messaging implementations in this manner, you will hopefully be able to follow this tutorial with minimal changes to your code.

Now, let’s create an adapter and name it MessageListAdapter. It will hold a List of Messages that will be displayed within a RecyclerView.

 

MessageListAdapter.java

By default, an adapter requires at least one RecyclerView.ViewHolder. It is a layout that can be inflated and bound by the objects it holds. In our case, two ViewHolders are needed:

  1. SentMessageHolder to hold messages that “I” sent
  2. ReceivedMessageHolder to hold messages that “I” have received from others

We’ll write these to be private inner classes of MessageListAdapter.

Each ViewHolder holds member views that can be bound to particular information contained in a message. For example, TextView messageText binds to a message’s content, while nameText binds to the name of a message’s sender.

Antonio Leiva suggests that we implement a bind(object) method within the ViewHolder class. This gives view binding to the ViewHolder class rather than to onBindViewHolder. It therefore produces cleaner code amidst multiple ViewHolders and ViewTypes. It also allows us to add easily OnClickListeners, if necessary.

 

ReceivedMessageHolder.java

SentMessageHolder will be identical except that it will not have nameText and profileImage.

Once you complete ViewHolder, turn back to the adapter and override the necessary methods to

  1. Obtain a message from MessageList
  2. Determine whether it is a sent message or a received message
  3. Inflate the appropriate layout for the ViewHolder
  4. Pass the message to the ViewHolder for binding

Implementing this process is standard for most types of adapters, and pretty self-explanatory; therefore, we’ll show the code for the full adapter without further explanation.

 

MessageListAdapter.java

We’ve just completed the adapter. We can now display a list of messages, both sent and received, in the chat bubbles that we defined earlier.

 

Putting it all together

We’ve created all the components, and now we need to initialize them inside our Activity. Instantiate a RecyclerView and a MessageListAdapter with a list of messages, and voila! You’ve just created your own messaging UI.

 

MessageListActivity.java

You can build more advanced features like “image preview,” animated GIFs within chat bubbles, and others. See examples of advanced chat UI at SendBird’s open source sample UI app! They build upon the use of RecyclerViews and adapters that we covered in this tutorial, and will help you create a production-level chat app with diverse features.

 

Edited by Alek Jeziorek on 08/16/2017.

Comments

6 Comments

How to build an Android chat app using a chat API - SendBird Blog

[…] to implement several XML files for the layout. This part is covered in depth in another blog post, Building a messaging UI – reference the link for more detailed descriptions. To summarize, you need three layouts: […]

Nicolas

Hey, nice tutorial!

Can you post the full example in a repository?

Wafaa

Great tutorial,thanks!

desgraci

the recycler view is always without height, fixed adding app:layout_constraintBottom_toBottomOf=”parent” but this doesn’t scroll the recyclerview when keyboard pops up

ahmed

I thought the position argument in getItemType(int position) is for the recycled views position not for the adapter
I mean if the screen fits 7 items for example we will have position values range between 0 and 6

ahmed

it turns out I was wrong and this tutorial saved my problem


Leave a Comment