前言
本来主要介绍了系统的textview
是如何显示,字体大小、文字颜色如何设置、文字的位置该如何计算
步骤
1、继承 View 重写构造方法
class CustomTextView @JvmOverloads constructor(context: Context,attr: AttributeSet?,defStyle:Int=0) :View(context,attr,defStyle)
这里使用的是
Kotlin
,所以构造函数看起来要简洁很多
2、初始化对象及自定义参数获取
var mPaint: Paint = Paint()
var mText: String?
var mTextSize = 0.0f
var mTextColor = Color.BLACK
init {
val ta = context.obtainStyledAttributes(attr, R.styleable.CustomTextView)
mText = ta.getString(R.styleable.CustomTextView_customText)
mTextSize = ta.getDimensionPixelSize(
R.styleable.CustomTextView_customTextSize,
sp2Px(DEFAULT_TEXT_SIZE)
).toFloat()
mTextColor = ta.getColor(R.styleable.CustomTextView_customTextColor, mTextColor)
ta.recycle()
mPaint.isAntiAlias = true
mPaint.color = mTextColor
mPaint.textSize = mTextSize
}
3、重新 onMeasure()
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
var widthMode = MeasureSpec.getMode(widthMeasureSpec)
var heightMode = MeasureSpec.getMode(heightMeasureSpec)
var widthSize = MeasureSpec.getSize(widthMeasureSpec)
var heightSize = MeasureSpec.getSize(heightMeasureSpec)
if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {//UNSPECIFIED:是为了兼容最外层是 ScrollView
val rect = Rect()
mPaint.getTextBounds(mText, 0, mText!!.length, rect)
//实际宽度 = 文字宽度 + view 的左右 padding
widthSize = rect.width() + paddingLeft + paddingRight
}
if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {//UNSPECIFIED:是为了兼容最外层是 ScrollView
val fontMetricsInt = mPaint.fontMetricsInt
//实际高度 = 文字高度 + view 的上下 padding
heightSize = fontMetricsInt.bottom-fontMetricsInt.top + paddingLeft + paddingRight
}
//一定要设置,这步是为了将测量好的宽高设置给 view
setMeasuredDimension(widthSize, heightSize)
}
MeasureSpec
包括了mode
(测量模式)、size
(测量大小)
`mode` xml
AT_MOST WRAP_CONTENT
EXACTLY 固定的值(50dp)或 MATCH_PARENT
UNSPECIFIED 无(一般系统内部使用)
4、重写 onDraw() 方法
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
val fontMetricsInt = mPaint.fontMetricsInt
//bottom 和 top 是到 baseLine 的距离(bottom 为正,top 为负)
val dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom
//vY 是文字的基线值
val vY = height / 2 + dy
canvas?.drawText(mText!!, paddingLeft.toFloat(), vY.toFloat(), mPaint)
}
<com.black.multi.customviewsample.demo01.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:paddingLeft="10dp"
android:paddingRight="20dp"
android:paddingTop="5dp"
android:paddingBottom="10dp"
app:customText="我是自定义CustomTextView"
app:customTextColor="@color/colorPrimary"
app:customTextSize="16sp" />
好了,到这里就结束了,简单的几步就可以实现文字的展示了,自定义 View 的基本步骤就如上面介绍的那样。这里总结一下:
- 重新构造函数(初始化会需要)
- 对象初始化及自定义属性的获取
- 重写 onMeasure() 方法(只有重新了该方法,绘制的内容才能正确的显示)
- 重写 onDraw() 方法(在这里绘制我们需要的内容,调用各种 drawXXX() 方法)