Click here to Skip to main content
14,037,415 members
Click here to Skip to main content
Add your own
alternative version

Stats

166.5K views
20 bookmarked
Posted 17 Apr 2015
Licenced CPOL

Designing Android Chat Bubble (Chat UI)

, 17 Apr 2015
Rate this:
Please Sign up or sign in to vote.
Creating Simple Android Chat Bubble or Chat UI Layout

Introduction

In this tip, we can see how a Chat Bubble (simply a Chat UI) is designed.

Background

It's common nowadays to have a Chat feature in many of the Mobile Applications. So here, we discuss quickly about how to design one for us. We will try to keep it short and crisp as much as possible to maintain the simplicity.

Screenshot

Using the Code

We will need to use a ListView to display the Chat list, listItem for displaying the individual Chat messages , Adapter to fill the ListView, Model Class which represents the Chat Messages and most important thing - 9 patch Images. The simplest explanation for 9 patch image will be an image which is set as background (Bubbles) and stretches accordingly with the text size. And its created just by saving any png image with an extension format. 9.png.

First, we start with creating an Activity and its Layout file which represents our Chat UI.

activity_chat.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">

    <RelativeLayout

        android:id="@+id/container"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical"

        android:padding="20dp">

        <EditText

            android:id="@+id/messageEdit"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_alignParentBottom="true"

            android:layout_toLeftOf="@+id/chatSendButton"

            android:autoText="true"

            android:hint="type message" />

        <Button

            android:id="@+id/chatSendButton"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_alignParentBottom="true"

            android:layout_alignParentRight="true"

            android:background="@color/background_floating_material_dark"

            android:text="Send MSG"

            android:textColor="@color/background_material_light"/>

        <ListView

            android:id="@+id/messagesContainer"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:layout_alignParentLeft="false"

            android:layout_alignParentTop="false"

            android:layout_marginBottom="20dp"

            android:layout_above="@+id/messageEdit"

            android:layout_below="@+id/meLbl"

            android:layout_marginTop="10dp"

            android:listSelector="@android:color/transparent"

            android:transcriptMode="alwaysScroll"

            android:divider="@null" />

        <TextView

            android:id="@+id/meLbl"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="left|center_vertical"

            android:text="MySelf"

            android:singleLine="false"

            android:textSize="20dp" />

        <TextView

            android:id="@+id/friendLabel"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_alignParentRight="true"

            android:text="Friend"

            android:textSize="20dp" />

    </RelativeLayout>
</LinearLayout>

ChatActivity.java

public class ChatActivity extends ActionBarActivity {

    private EditText messageET;
    private ListView messagesContainer;
    private Button sendBtn;
    private ChatAdapter adapter;
    private ArrayList<ChatMessage> chatHistory;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        initControls();
    }
   
    private void initControls() {
        messagesContainer = (ListView) findViewById(R.id.messagesContainer);
        messageET = (EditText) findViewById(R.id.messageEdit);
        sendBtn = (Button) findViewById(R.id.chatSendButton);

        TextView meLabel = (TextView) findViewById(R.id.meLbl);
        TextView companionLabel = (TextView) findViewById(R.id.friendLabel);
        RelativeLayout container = (RelativeLayout) findViewById(R.id.container);
        companionLabel.setText("My Buddy");// Hard Coded
        loadDummyHistory();

        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String messageText = messageET.getText().toString();
                if (TextUtils.isEmpty(messageText)) {
                    return;
                }

                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setId(122);//dummy
                chatMessage.setMessage(messageText);
                chatMessage.setDate(DateFormat.getDateTimeInstance().format(new Date()));
                chatMessage.setMe(true);

                messageET.setText("");

                displayMessage(chatMessage);
            }
        });
    }

    public void displayMessage(ChatMessage message) {
        adapter.add(message);
        adapter.notifyDataSetChanged();
        scroll();
    }

    private void scroll() {
        messagesContainer.setSelection(messagesContainer.getCount() - 1);
    }

    private void loadDummyHistory(){

        chatHistory = new ArrayList<ChatMessage>();

        ChatMessage msg = new ChatMessage();
        msg.setId(1);
        msg.setMe(false);
        msg.setMessage("Hi");
        msg.setDate(DateFormat.getDateTimeInstance().format(new Date()));
        chatHistory.add(msg);
        ChatMessage msg1 = new ChatMessage();
        msg1.setId(2);
        msg1.setMe(false);
        msg1.setMessage("How r u doing???");
        msg1.setDate(DateFormat.getDateTimeInstance().format(new Date()));
        chatHistory.add(msg1);

        adapter = new ChatAdapter(ChatActivity.this, new ArrayList<ChatMessage>());
        messagesContainer.setAdapter(adapter);

                for(int i=0; i<chatHistory.size(); i++) {
                    ChatMessage message = chatHistory.get(i);
                    displayMessage(message);
                }
    }
}

List Item which shows the individual chat messages and the Background of this text will be set as Chat Bubble (our 9 patch image).

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content">
    <LinearLayout

        android:id="@+id/content"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:orientation="vertical">

        <TextView

            android:id="@+id/txtInfo"

            android:layout_width="wrap_content"

            android:layout_height="30sp"

            android:layout_gravity="right"

            android:textSize="12sp"

            android:textColor="@android:color/darker_gray" />

        <LinearLayout

            android:id="@+id/contentWithBackground"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="right"

            android:background="@drawable/in_message_bg"

            android:paddingLeft="10dp"

            android:paddingBottom="10dp"

            android:orientation="vertical">

            <TextView

                android:id="@+id/txtMessage"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:textColor="@android:color/black"

                android:maxWidth="240dp" />

        </LinearLayout>

    </LinearLayout>
</RelativeLayout>

Now we require a Model Class for representing the Chat Message and an Adapter to fill it for the ListView.

ChatMessage.java

public class ChatMessage {
    private long id;
    private boolean isMe;
    private String message;
    private Long userId;
    private String dateTime;

    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public boolean getIsme() {
        return isMe;
    }
    public void setMe(boolean isMe) {
        this.isMe = isMe;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public String getDate() {
        return dateTime;
    }

    public void setDate(String dateTime) {
        this.dateTime = dateTime;
    }
}

ChatAdapter.java

As usual, we use ViewHolder pattern for efficiency when recreating each items in the Listview. LayoutParams are for designing the Layout left or right aligned according to the Chat Message Send or Received. A dummy boolean value is used as the property to check whether its Send or Received for simplicity .

public class ChatAdapter extends BaseAdapter {

    private final List<ChatMessage> chatMessages;
    private Activity context;

    public ChatAdapter(Activity context, List<ChatMessage> chatMessages) {
        this.context = context;
        this.chatMessages = chatMessages;
    }

    @Override
    public int getCount() {
        if (chatMessages != null) {
            return chatMessages.size();
        } else {
            return 0;
        }
    }

    @Override
    public ChatMessage getItem(int position) {
        if (chatMessages != null) {
            return chatMessages.get(position);
        } else {
            return null;
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        ChatMessage chatMessage = getItem(position);
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = vi.inflate(R.layout.list_item_chat_message, null);
            holder = createViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        boolean myMsg = chatMessage.getIsme() ;//Just a dummy check 
        		//to simulate whether it me or other sender
        setAlignment(holder, myMsg);
        holder.txtMessage.setText(chatMessage.getMessage());
        holder.txtInfo.setText(chatMessage.getDate());

        return convertView;
    }

    public void add(ChatMessage message) {
        chatMessages.add(message);
    }

    public void add(List<ChatMessage> messages) {
        chatMessages.addAll(messages);
    }

    private void setAlignment(ViewHolder holder, boolean isMe) {
        if (!isMe) {
            holder.contentWithBG.setBackgroundResource(R.drawable.in_message_bg);

            LinearLayout.LayoutParams layoutParams = 
            	(LinearLayout.LayoutParams) holder.contentWithBG.getLayoutParams();
            layoutParams.gravity = Gravity.RIGHT;
            holder.contentWithBG.setLayoutParams(layoutParams);

            RelativeLayout.LayoutParams lp = 
            	(RelativeLayout.LayoutParams) holder.content.getLayoutParams();
            lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            holder.content.setLayoutParams(lp);
            layoutParams = (LinearLayout.LayoutParams) holder.txtMessage.getLayoutParams();
            layoutParams.gravity = Gravity.RIGHT;
            holder.txtMessage.setLayoutParams(layoutParams);

            layoutParams = (LinearLayout.LayoutParams) holder.txtInfo.getLayoutParams();
            layoutParams.gravity = Gravity.RIGHT;
            holder.txtInfo.setLayoutParams(layoutParams);
        } else {
            holder.contentWithBG.setBackgroundResource(R.drawable.out_message_bg);

            LinearLayout.LayoutParams layoutParams = 
            	(LinearLayout.LayoutParams) holder.contentWithBG.getLayoutParams();
            layoutParams.gravity = Gravity.LEFT;
            holder.contentWithBG.setLayoutParams(layoutParams);

            RelativeLayout.LayoutParams lp = 
            	(RelativeLayout.LayoutParams) holder.content.getLayoutParams();
            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
            lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            holder.content.setLayoutParams(lp);
            layoutParams = (LinearLayout.LayoutParams) holder.txtMessage.getLayoutParams();
            layoutParams.gravity = Gravity.LEFT;
            holder.txtMessage.setLayoutParams(layoutParams);

            layoutParams = (LinearLayout.LayoutParams) holder.txtInfo.getLayoutParams();
            layoutParams.gravity = Gravity.LEFT;
            holder.txtInfo.setLayoutParams(layoutParams);
        }
    }

    private ViewHolder createViewHolder(View v) {
        ViewHolder holder = new ViewHolder();
        holder.txtMessage = (TextView) v.findViewById(R.id.txtMessage);
        holder.content = (LinearLayout) v.findViewById(R.id.content);
        holder.contentWithBG = (LinearLayout) v.findViewById(R.id.contentWithBackground);
        holder.txtInfo = (TextView) v.findViewById(R.id.txtInfo);
        return holder;
    }

    private static class ViewHolder {
        public TextView txtMessage;
        public TextView txtInfo;
        public LinearLayout content;
        public LinearLayout contentWithBG;
    }
}

Now, that's all we need to accomplish our task of designing a Chat Bubble. This sample was created using Android Studio IDE. I have posted the complete code which can be downloaded.

Points of Interest

The sample is designed for making it easy to try it yourself. Happy coding. :) Please do contact me in case of any doubts or queries.

History

  • 17th April, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

JoCodes
CEO Technovibe Solutions
India India
A web developer by profession in Microsoft technology stack and later into Mobile App Development. Indulges in a variety of hobbies such as travelling, photography, driving , biking etc.

You may also be interested in...

Comments and Discussions

 
SuggestionHow to edit and delete the message once posted. And finally save entire chat as image. Pin
Rakesh Shah18-Nov-17 5:06
memberRakesh Shah18-Nov-17 5:06 
QuestionHow to get buttons, images, videos and URLs specifically for a particular message/text in this code? Pin
Member 131725324-May-17 4:49
memberMember 131725324-May-17 4:49 
Bugerror Pin
Member 1316184629-Apr-17 19:49
memberMember 1316184629-Apr-17 19:49 
QuestionHello Pin
Member 1305327611-Mar-17 10:52
memberMember 1305327611-Mar-17 10:52 
AnswerRe: Hello Pin
JoCodes3-Apr-17 18:48
memberJoCodes3-Apr-17 18:48 
News[My vote of 1] bad this Pin
Member 128408696-Dec-16 0:04
memberMember 128408696-Dec-16 0:04 
QuestionHelp me to get reply message Pin
Member 1249588531-Jul-16 20:32
memberMember 1249588531-Jul-16 20:32 
AnswerRe: Help me to get reply message Pin
JoCodes11-Sep-16 6:40
memberJoCodes11-Sep-16 6:40 
Questionconnect Database Pin
Member 1257654310-Jun-16 1:32
memberMember 1257654310-Jun-16 1:32 
AnswerRe: connect Database Pin
JoCodes12-Jun-16 5:27
memberJoCodes12-Jun-16 5:27 
QuestionAdding picture from a gallery or camera to chat bubble Pin
Member ATC26-May-16 9:52
memberMember ATC26-May-16 9:52 
AnswerRe: Adding picture from a gallery or camera to chat bubble Pin
JoCodes12-Jun-16 5:25
memberJoCodes12-Jun-16 5:25 
GeneralRe: Adding picture from a gallery or camera to chat bubble Pin
Member ATC12-Jun-16 21:17
memberMember ATC12-Jun-16 21:17 
GeneralRe: Adding picture from a gallery or camera to chat bubble Pin
JoCodes12-Jun-16 21:59
memberJoCodes12-Jun-16 21:59 
GeneralRe: Adding picture from a gallery or camera to chat bubble Pin
Member ATC13-Jun-16 2:05
memberMember ATC13-Jun-16 2:05 
Questionretrieving the data from database Pin
Member 1233750729-Feb-16 6:39
memberMember 1233750729-Feb-16 6:39 
QuestionHow do I display a single calendar date on top for a batch of messages from the same day? Pin
Member 964606319-Oct-15 15:23
memberMember 964606319-Oct-15 15:23 
AnswerRe: How do I display a single calendar date on top for a batch of messages from the same day? Pin
JoCodes16-Nov-15 18:43
memberJoCodes16-Nov-15 18:43 
QuestionUpdating a single row Pin
Tanya Visagie28-Sep-15 10:55
memberTanya Visagie28-Sep-15 10:55 
AnswerRe: Updating a single row Pin
JoCodes16-Nov-15 18:41
memberJoCodes16-Nov-15 18:41 
QuestionRequirements for backend services Pin
Member 1140203313-Jul-15 5:11
memberMember 1140203313-Jul-15 5:11 
AnswerRe: Requirements for backend services Pin
JoCodes13-Jul-15 6:58
memberJoCodes13-Jul-15 6:58 
QuestionMy Vote of 5 Pin
Hajish R I22-Apr-15 9:48
memberHajish R I22-Apr-15 9:48 
AnswerRe: My Vote of 5 Pin
JoCodes22-Apr-15 9:53
memberJoCodes22-Apr-15 9:53 
QuestionMy Vote of 5 Pin
Mekki Ahmedi20-Apr-15 20:34
memberMekki Ahmedi20-Apr-15 20:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190424.1 | Last Updated 17 Apr 2015
Article Copyright 2015 by JoCodes
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid