自定义 View 实战 01 - TextView

2020-06-16 14:57:34 浏览数 (1)

前言

本来主要介绍了系统的textview是如何显示,字体大小、文字颜色如何设置、文字的位置该如何计算

步骤

1、继承 View 重写构造方法

代码语言:javascript复制
class CustomTextView @JvmOverloads constructor(context: Context,attr: AttributeSet?,defStyle:Int=0) :View(context,attr,defStyle)

这里使用的是Kotlin,所以构造函数看起来要简洁很多

2、初始化对象及自定义参数获取

代码语言:javascript复制
    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() **

代码语言:javascript复制
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(测量大小)

代码语言:javascript复制
`mode`                       xml
AT_MOST                  WRAP_CONTENT
EXACTLY                  固定的值(50dp)或 MATCH_PARENT
UNSPECIFIED              无(一般系统内部使用)
代码语言:javascript复制
<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" />

自定义TextView

好了,到这里就结束了,简单的几步就可以实现文字的展示了,自定义 View 的基本步骤就如上面介绍的那样。这里总结一下:

  • 重新构造函数(初始化会需要)
  • 对象初始化及自定义属性的获取
  • 重写 onMeasure() 方法(只有重新了该方法,绘制的内容才能正确的显示)
  • 重写 onDraw() 方法(在这里绘制我们需要的内容,调用各种 drawXXX() 方法)

0 人点赞