自己很少写自定义控件,这次见到一个tab的背景卡片不算复杂,刚好开发时间也充足,就写一个练练手,也记录一下写的过程,方便日后查看。
话不多说,直接上代码
class CardTabBg : View {
private var radius = 0
private var gapWidth = 0
private var locationMode = 0
constructor(context: Context?) : super(context) {
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
initAttr(context, attrs)
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
initAttr(context, attrs)
}
constructor(
context: Context?,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes) {
initAttr(context, attrs)
}
private fun initAttr(context: Context?, attrs: AttributeSet?) {
val att = context!!.obtainStyledAttributes(
attrs, R.styleable.CardTab)
locationMode = att.getInt(R.styleable.CardTab_card_location_type, 0)
radius = att.getDimensionPixelSize(R.styleable.CardTab_radiusSize, 0)
gapWidth = att.getDimensionPixelSize(R.styleable.CardTab_gapSize, 0)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (canvas != null) {
if (locationMode == 0) {
var paint = Paint()
paint.color = ResourceUtil.getColor(context, R.color.white)
paint.style = Paint.Style.FILL
paint.isAntiAlias = true
var path = Path()
path.moveTo(0f, radius.toFloat())
path.quadTo(0f, 0f, radius.toFloat(), 0f)
path.lineTo(width - radius.toFloat() - gapWidth, 0f)
path.quadTo(
width - radius * 0.6f - gapWidth,
0f,
width - radius.toFloat() / 2 - gapWidth,
radius.toFloat() / 2
)
path.lineTo(width.toFloat(), height.toFloat())
path.lineTo(0f, height.toFloat())
path.lineTo(0f, radius.toFloat())
path.close()
canvas.drawPath(path, paint)
} else {
var paint = Paint()
paint.color = ResourceUtil.getColor(context, R.color.white)
paint.style = Paint.Style.FILL
paint.isAntiAlias = true
var path = Path()
path.moveTo(0f, height.toFloat())
path.lineTo(gapWidth + radius.toFloat() / 2, radius.toFloat() / 2)
path.quadTo(
radius * 0.6f + gapWidth,
0f,
radius.toFloat() + gapWidth,
0f
)
path.lineTo(width - radius.toFloat(), 0f)
path.quadTo(
width.toFloat() ,
0f,
width.toFloat(),
radius.toFloat()
)
path.lineTo(width.toFloat(), height.toFloat())
path.lineTo(0f, height.toFloat())
path.close()
canvas.drawPath(path, paint)
}
}
}
}
res/values/attrs 文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CardTab">
<attr name="radiusSize" format="dimension" />
<attr name="gapSize" format="dimension" />
<attr name="card_location_type" format="enum">
<enum name="location_start" value="0" /><!-- 居左tab -->
<enum name="location_middle" value="1" /> <!--中间tab-->
<enum name="location_end" value="2" /> <!--居右tab-->
</attr>
</declare-styleable>
</resources>
此图效果类似于圆角矩形,只是一侧为斜线效果。效果如下