1. 使用
项目中遇到一个需求,一段文字的背景是类似于对话框那样带有箭头,如图:
刚开始的想法是通过Tooltip库展示,但是由于箭头位置需要自定义,作者没有提供入口。后根据该库中提供的TooltipTextDrawable,想到自定义Drawable,偶然发现material包中提供了TooltipDrawable,但是不允许外部使用,代码如下:
@RestrictTo(LIBRARY_GROUP)
public class TooltipDrawable extends MaterialShapeDrawable implements TextDrawableDelegate
但是该类的父类MaterialShapeDrawable是可以使用的,经过查询资料发现使用很简单,也不用自定义Drawable,也不用额外导入库。故记录一下用法。
val appearanceModel = ShapeAppearanceModel.builder()
.setAllCornerSizes(DisplayUtils.dp2pxF(6F))
.setBottomEdge(OffsetEdgeTreatment(
TriangleEdgeTreatment(DisplayUtils.dp2pxF(6F), false),
DisplayUtils.dp2pxF(10F)))
.build()
val drawable = MaterialShapeDrawable(appearanceModel).apply {
setTint(Color.parseColor("#FA4B05"))
paintStyle = Paint.Style.FILL
}
tv_tip.background = drawable
创建MaterialShapeDrawable对象,构造方法需要传入ShapeAppearanceModel参数,通过ShapeAppearanceModel可以设置各个角、各个边的效果,这些效果通过各种treatment实现。
2. 样式
已有的各种treatment如下:
- CornerTreatment
- RoundedCornerTreatment 圆角方案
- CutCornerTreatment 折角方案
- EdgeTreatment
- TriangleEdgeTreatment 三角形
- MarkerEdgeTreatment 类似于地图的兴趣点
- OffsetEdgeTreatment 位移
- BottomAppBarTopEdgeTreatment 应该是中间带有悬浮按钮的效果
效果一
val shapePathModel = ShapePathModel().apply {
setAllCorners(CutCornerTreatment(dip(5).toFloat()))
setAllEdges(TriangleEdgeTreatment(dip(5).toFloat(), true))
}
val backgroundDrawable = MaterialShapeDrawable(shapePathModel).apply {
setTint(ContextCompat.getColor(this@MainActivity, R.color.colorPrimary))
paintStyle = Paint.Style.FILL
}
textView.background = backgroundDrawable
效果二
class CutoutCornersTreatment(val size: Float) : CornerTreatment() {
override fun getCornerPath(angle: Float, interpolation: Float, shapePath: ShapePath) {
shapePath.reset(0.0f, size * interpolation)
shapePath.lineTo(size * interpolation, size * interpolation)
shapePath.lineTo(size * interpolation, 0f)
}
}
class CurvedEdgeTreatment(val size: Float) : EdgeTreatment() {
override fun getEdgePath(length: Float, interpolation: Float, shapePath: ShapePath) {
shapePath.quadToPoint(length / 2f, size * interpolation, length, 0f)
}
}
以上两种效果引用自参考文章2
3. 遇到的问题
在使用中遇到一个问题,箭头向内有效果,但是箭头向下竟然没有效果,经查询需要在应用drawable的父类中增加如下参数:
android:clipChildren="false"
android:clipToPadding="false"