Вот простой речевой пузырь, который я нарисовал. Надеюсь, это начало в правильном направлении для кого-то. Представление о том, что это рисование используется, нуждается в высоте не менее 70-80 dp и аналогичной минимальной ширине, чтобы показать правильно.
<?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 оставляет желать лучшего с точки зрения того, насколько они полезны для рисования чего-либо, даже немного сложного.
Эта версия выглядит так:
![Old speech bubble version](https://i.stack.imgur.com/0gLrY.png)
ОБНОВЛЕНИЕ Я снова работал над речевыми пузырями XML и был немного недоволен своим решением 2014 года. В 2018 году у нас есть векторные графики, которые обеспечивают лучшие решения, чем приведенные выше. Вот еще несколько современных альтернатив. Они позволяют такие вещи, как небольшие сообщения и прозрачность.
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>
Два приведенных выше выглядят так: (Эти версии не совсем работают с прозрачностью, и я не уверен, почему, когда представленные ниже версии работают нормально.)
![Two simple speech bubbles](https://i.stack.imgur.com/Fy5rm.png)
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>
Два приведенных выше выглядят так:
![Speech bubbles with curly tails](https://i.stack.imgur.com/vaaiO.png)
Dimens.xml (для обоих)
<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>