Here is a simple speech bubble drawable I made. Hopefully, it's start in the right direction for someone. The view that this drawable is used in needs a height of at least 70-80dp and a similar minimum width to show properly.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:top="30dp">
<rotate
android:fromDegrees="-45"
android:pivotX="0%"
android:pivotY="0%"
android:toDegrees="0" >
<shape android:shape="rectangle" >
<solid android:color="#CCC" />
</shape>
</rotate>
</item>
<item android:left="20dp">
<shape android:shape="rectangle" >
<solid android:color="#CCC" />
<corners android:radius="5dp" />
</shape>
</item>
</layer-list>
Android Drawables leave a lot to be desired in terms of how usable they are for drawing anything even slightly complex.
This version looks like this:
UPDATE I've been working on XML speech bubbles again and was a little dissatisfied with my 2014 solution. In 2018, we have vector drawables which enable better solutions than the one above. Here are some more modern alternatives. They allow things like small messages and transparency.
speech_bubble_simple_user.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:bottom="@dimen/speech_bubble_tail"
tools:width="100dp"
tools:height="50dp">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_user"/>
<corners
android:topLeftRadius="@dimen/speech_bubble_corners"
android:topRightRadius="@dimen/speech_bubble_corners"
android:bottomRightRadius="0dp"
android:bottomLeftRadius="@dimen/speech_bubble_corners"/>
</shape>
</item>
<item
android:width="@dimen/speech_bubble_tail"
android:height="@dimen/speech_bubble_tail"
android:gravity="bottom|right">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_tail"
android:height="@dimen/speech_bubble_tail"
android:viewportWidth="25.0"
android:viewportHeight="25.0">
<path
android:pathData="M25,25 25,0 0,0z"
android:fillColor="@color/speech_bubble_user"/>
</vector>
</item>
</layer-list>
speech_bubble_simple_agent.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:bottom="@dimen/speech_bubble_tail"
tools:width="100dp"
tools:height="50dp">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_agent"/>
<corners
android:topLeftRadius="@dimen/speech_bubble_corners"
android:topRightRadius="@dimen/speech_bubble_corners"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="@dimen/speech_bubble_corners"/>
</shape>
</item>
<item
android:width="@dimen/speech_bubble_tail"
android:height="@dimen/speech_bubble_tail"
android:gravity="bottom|left">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_tail"
android:height="@dimen/speech_bubble_tail"
android:viewportWidth="25.0"
android:viewportHeight="25.0">
<path
android:pathData="M0,25 25,0 0,0z"
android:fillColor="@color/speech_bubble_agent"/>
</vector>
</item>
</layer-list>
The two above look like this: (These versions don't quite work with transparency and I'm not sure why when the versions below seem to work fine.)
speech_bubble_nine_patch_user.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:left="@dimen/speech_bubble_corners"
android:right="@dimen/speech_bubble_corners_plus_tail"
android:bottom="@dimen/speech_bubble_spacing"
tools:width="50dp"
tools:height="50dp">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_user"/>
</shape>
</item>
<item
android:top="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_corners_plus_tail"
android:gravity="left"
android:width="@dimen/speech_bubble_corners">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_user"/>
</shape>
</item>
<item
android:top="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_corners_plus_tail"
android:right="@dimen/speech_bubble_spacing"
android:gravity="right"
android:width="@dimen/speech_bubble_corners">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_user"/>
</shape>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_spacing"
android:gravity="bottom|left">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M0,0 A10,10 0 0,0 10,10 L10,0 Z"
android:fillColor="@color/speech_bubble_user"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:right="@dimen/speech_bubble_spacing"
android:gravity="top|right">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M10,10 A10,10 0 0,0 0,0 L0,10 Z"
android:fillColor="@color/speech_bubble_user"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:gravity="top|left">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M10,0 A10,10 0 0,0 0,10 L10,10 Z"
android:fillColor="@color/speech_bubble_user"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners_plus_tail"
android:height="@dimen/speech_bubble_corners_plus_tail"
android:gravity="bottom|right">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners_plus_tail"
android:height="@dimen/speech_bubble_corners_plus_tail"
android:viewportWidth="150.0"
android:viewportHeight="150.0">
<path
android:pathData="M0,100 C7.67309143,100 14.1935201,100.346373 20.500756,99.0996492 C43.6628959,129.872031 94.1698247,146.306561 150.320843,150.792562 C113.168693,130.799632 87.2808993,98.5054948 81.0808824,68.6524321 C94.1277117,51.7595331 100,23.9957121 100,0 L0,0 L0,100 Z"
android:fillColor="@color/speech_bubble_user"/>
</vector>
</item>
</layer-list>
speech_bubble_nine_patch_agent.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<item
android:left="@dimen/speech_bubble_corners_plus_tail"
android:right="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_spacing"
tools:width="50dp"
tools:height="50dp">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_agent"/>
</shape>
</item>
<item
android:top="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_corners_plus_tail"
android:left="@dimen/speech_bubble_spacing"
android:gravity="left"
android:width="@dimen/speech_bubble_corners">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_agent"/>
</shape>
</item>
<item
android:top="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_corners_plus_tail"
android:gravity="right"
android:width="@dimen/speech_bubble_corners">
<shape android:shape="rectangle">
<solid android:color="@color/speech_bubble_agent"/>
</shape>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:bottom="@dimen/speech_bubble_spacing"
android:gravity="bottom|right">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M0,10 A10,10 0 0,0 10,0 L0,0 Z"
android:fillColor="@color/speech_bubble_agent"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:gravity="top|right">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M10,10 A10,10 0 0,0 0,0 L0,10 Z"
android:fillColor="@color/speech_bubble_agent"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:left="@dimen/speech_bubble_spacing"
android:gravity="top|left">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners"
android:height="@dimen/speech_bubble_corners"
android:viewportWidth="10.0"
android:viewportHeight="10.0">
<path
android:pathData="M10,0 A10,10 0 0,0 0,10 L10,10 Z"
android:fillColor="@color/speech_bubble_agent"/>
</vector>
</item>
<item
android:width="@dimen/speech_bubble_corners_plus_tail"
android:height="@dimen/speech_bubble_corners_plus_tail"
android:gravity="bottom|left">
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/speech_bubble_corners_plus_tail"
android:height="@dimen/speech_bubble_corners_plus_tail"
android:viewportWidth="150.0"
android:viewportHeight="150.0">
<path
android:pathData="M150,100 L150,0 L50,0 C50,11.9054549 52.5180742,22.2130322 55.2200144,32.2289993 C59.25,47.1679688 65.7054859,60.8615415 68.15625,65.5820312 C55.2200144,107.207031 41.7460938,127.800781 0,151 C61.5311854,147.539062 101.691406,129.675781 124.615295,97.6602593 C132.823321,99.8389881 141.106342,100 150,100 Z"
android:fillColor="@color/speech_bubble_agent"/>
</vector>
</item>
</layer-list>
The two above look like this:
dimens.xml (for both)
<dimen name="speech_bubble_corners">10dp</dimen>
<dimen name="speech_bubble_corners_plus_tail">15dp</dimen>
<dimen name="speech_bubble_spacing">5dp</dimen>
<dimen name="speech_bubble_tail">25dp</dimen>