Implementing Chat Bubbles in Android Messaging Applications
Chat bubbles in Android are implemented using a ListView with a custom adapter that switches between two layout files based on message direction. A boolean variable in the message data class determines whether a message is sent or received, guiding the adapter's getView() method to inflate the appropriate layout.
Layout for Received Messages (chat_item_received.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar_received"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/avatar_default" />
<RelativeLayout
android:id="@+id/bubble_container_received"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/avatar_received"
android:background="@drawable/bubble_received">
<TextView
android:id="@+id/text_received"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="160dp"/>
</RelativeLayout>
<TextView
android:id="@+id/timestamp_received"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/avatar_received"
android:layout_below="@id/bubble_container_received"
android:textSize="10sp" />
</RelativeLayout>
Layout for Sent Messaegs (chat_item_sent.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="@drawable/avatar_default" />
<RelativeLayout
android:id="@+id/bubble_container_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/avatar_sent"
android:background="@drawable/bubble_sent">
<TextView
android:id="@+id/text_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="160dp" />
</RelativeLayout>
<TextView
android:id="@+id/timestamp_sent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/bubble_container_sent"
android:layout_toLeftOf="@+id/avatar_sent"
android:textSize="10sp"/>
</RelativeLayout>
In the adapter, the message direction is checked to select the correct layout:
if (message.isReceived()) {
convertView = inflater.inflate(R.layout.chat_item_received, null);
} else {
convertView = inflater.inflate(R.layout.chat_item_sent, null);
}