Android XML实现带尾巴的聊天消息背景Drawable
Android 实现带尾巴的聊天消息背景方案
下面给你三种实用的实现方式,按需选择:
方法一:VectorDrawable 矢量图实现(推荐)
矢量图支持自适应拉伸且不失真,适合简单的圆角+尾巴样式。以左侧尾巴的消息为例,创建 drawable/chat_bubble_left.xml:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="240dp" android:height="120dp" android:viewportWidth="240" android:viewportHeight="120"> <!-- 主背景+左下角尾巴 --> <path android:fillColor="#E5E5EA" android:pathData="M20,0 L220,0 L220,100 L20,100 L20,20 L0,10 L20,0 Z" /> </vector>
如果是右侧尾巴的消息,调整 pathData 把尾巴放在右下角即可:
<path android:fillColor="#007AFF" android:pathData="M20,0 L220,0 L220,10 L240,20 L220,30 L220,100 L20,100 Z" />
使用时直接将其设为 TextView 或布局的 background,还能通过 android:tint 修改颜色。
方法二:9-Patch 图片实现
适合复杂样式,上手快:
- 用设计工具(PS/Sketch)绘制带尾巴的背景图,注意尾巴部分不要做拉伸处理
- 在 Android Studio 中右键图片 →
Create 9-Patch file,用工具标记可拉伸区域和内容显示区域 - 将生成的
.9.png放入drawable目录,直接作为 View 的背景使用
方法三:自定义 Drawable 代码实现
需要动态调整尾巴方向、大小或颜色时用这种方式:
class ChatBubbleDrawable(private val isRightBubble: Boolean) : Drawable() { private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = if (isRightBubble) Color.parseColor("#007AFF") else Color.parseColor("#E5E5EA") } private val path = Path() override fun draw(canvas: Canvas) { val bounds = bounds val cornerRadius = 16f // 圆角大小 val tailWidth = 12f // 尾巴宽度 val tailHeight = 16f // 尾巴高度 path.reset() // 绘制主圆角矩形 val rectLeft = if (isRightBubble) bounds.left.toFloat() else bounds.left + tailWidth val rectRight = if (isRightBubble) bounds.right - tailWidth else bounds.right.toFloat() path.addRoundRect( rectLeft, bounds.top.toFloat(), rectRight, bounds.bottom.toFloat(), cornerRadius, cornerRadius, Path.Direction.CW ) // 添加尾巴路径 val tailX = if (isRightBubble) bounds.right.toFloat() else bounds.left.toFloat() val tailY = bounds.bottom - tailHeight path.moveTo(tailX, tailY) path.lineTo(if (isRightBubble) tailX - tailWidth else tailX + tailWidth, bounds.bottom.toFloat()) path.lineTo(if (isRightBubble) tailX - tailWidth else tailX + tailWidth, tailY + tailHeight / 2) path.close() canvas.drawPath(path, paint) } override fun setAlpha(alpha: Int) { paint.alpha = alpha } override fun setColorFilter(colorFilter: ColorFilter?) { paint.colorFilter = colorFilter } override fun getOpacity(): Int = PixelFormat.TRANSLUCENT }
使用示例:
// 给TextView设置右侧气泡背景 messageTv.background = ChatBubbleDrawable(isRightBubble = true)
内容的提问来源于stack exchange,提问作者Roop Kishore
相关产品推荐
相关产品推荐

