效果圖:
effect0.jpg
產(chǎn)品需求:
制作產(chǎn)品標(biāo)簽卡外邓。限定高度,自適用寬度(Max限制). 兩種類型奕短,產(chǎn)品或其他宜肉。產(chǎn)品的時候上面是產(chǎn)品名,下面是價格翎碑。其他只有一行文案谬返。左邊的圖片也不同(總共8種不同類型)。
實(shí)現(xiàn)思路(偽代碼):
1.先畫出左邊的ICON下面的圓形日杈。
canvas.drawCircle(x ,y)
- 圓內(nèi)畫出ICON遣铝。
canvas.drawBitmap(bitmap, x, y, paint)
3.以圓坐標(biāo)加圓半徑的距離開始畫三角形。
path.moveTo(x,y)
path.lineTo(x,y)
path.lineTo(x,y)
path.close()
canvas.drawPath(path,paint)
4.從三角形的右邊坐標(biāo)畫圓角四邊形莉擒。
canvas.drawRoundRect(react,radius,radius,paint)
- 畫出文字酿炸。
canvas.drawText(text,x,y,paint)
實(shí)現(xiàn)
還是繼承View。并且重寫三個必須的構(gòu)造方法和兩個方法涨冀。由于產(chǎn)品卡數(shù)量的不確定性,也不能設(shè)置封裝對象作為屬性填硕。只能通過傳值到View來進(jìn)行多個標(biāo)簽的渲染。
- 重寫結(jié)構(gòu)體:
class PostTagView : View {
constructor(mContext: Context) : super(mContext)
constructor(mContext: Context, attributeSet: AttributeSet) : super(mContext, attributeSet)
constructor(mContext: Context, attributeSet: AttributeSet, theme: Int) : super(
mContext,
attributeSet,
theme
)
}
- 定義使用的變量鹿鳖。
/**
* React 四邊形坐標(biāo)點(diǎn)
*/
var react= RectF()
/**
* M paint 畫C1C1C1 為背景扁眯。
* 注:抗鋸齒關(guān)閉(為了性能)
* @see Paint.isAntiAlias
*/
private lateinit var mPaint:Paint
/**
* T paint 畫文案
* 抗鋸齒已開。
* 顏色白色翅帜。
*/
private lateinit var tPaint:Paint
/**
* C paint 透明背景
*/
private lateinit var cPaint:Paint
/**
* Path 路徑 畫三角形
*/
private lateinit var path:Path
/**
* Bitmap 解析Bitmap
*/
private lateinit var bitmap: Bitmap
3.初始化變量姻檀。
/**
* Init params
* 這里會初始化一些變量。
*/
private fun initParams() {
//初始化 主要顏色
mPaint = Paint()
mPaint.isAntiAlias=false
mPaint.color = Color.parseColor("#1c1c1c")
mPaint.style = Paint.Style.FILL
//初始化 文字
tPaint= Paint()
tPaint.isAntiAlias=true
tPaint.color = Color.WHITE
tPaint.textSize=DisplayUtils.dip2px(12F).toFloat()
tPaint.typeface= Typeface.DEFAULT_BOLD
//初始化Path
path=Path()
//初始化cPaint
cPaint= Paint()
cPaint.color=Color.parseColor("#B31c1c1c")
cPaint.isAntiAlias=false
}
- 渲染
/**
* Draw other 除了產(chǎn)品 畫其他Tag
*
* @param src 資源(R.drawable.xxx)
* @param x 初始x坐標(biāo)
* @param y 初始y坐標(biāo)
* @param content 文案
* @param canvas Canvas
*/
fun drawOtherTag(src:Int,x:Float,y:Float,content:String,canvas: Canvas?){
//解決文字的長度問題
var temp= if (content.length>13){
content.substring(0..13)+"..."
}else{
content
}
val drawable=AppCompatResources.getDrawable(context,src)
bitmap=drawable!!.toBitmap(DisplayUtils.dip2px(20F),DisplayUtils.dip2px(20F))
canvas?.drawCircle(x,y,DisplayUtils.dip2px( 15f).toFloat(),cPaint)
path.moveTo(x+DisplayUtils.dip2px(15F).toFloat(),y)
path.lineTo(x+DisplayUtils.dip2px(25F),y+DisplayUtils.dip2px(10F))
path.lineTo(x+DisplayUtils.dip2px(25F),y+DisplayUtils.dip2px(-10F))
path.close()
canvas?.drawPath(path,mPaint)
react= RectF(x+DisplayUtils.dip2px(25F),y-DisplayUtils.dip2px(20F),x+tPaint.measureText(temp)+DisplayUtils.dip2px(50F),y+DisplayUtils.dip2px(20F))
canvas!!.drawRoundRect(react,30F,30F,mPaint)
canvas.drawText(temp,x+DisplayUtils.dip2px(35F),y+DisplayUtils.dip2px(3F),tPaint)
canvas.drawBitmap(bitmap,x-DisplayUtils.dip2px(10F),y-DisplayUtils.dip2px(10F),null)
canvas.save()
}
注明一下:我之所以使用dp轉(zhuǎn)pixel的值涝滴,是為了兼容不同設(shè)備下顯示相同大小的object绣版。Canvas的值是pixel為單位的。
最后效果圖:
effects.png