美文网首页
Android自定义View(8) 《绘制文本》

Android自定义View(8) 《绘制文本》

作者: 非典型程序猿 | 来源:发表于2021-09-05 14:50 被阅读0次

概述

在Android中,我们经常会需要去绘制一些自己需要的控件,所以继承自View的自定义View就产生了。这篇文章主要介绍如何在我们的自定义View中绘制Text

示例

package com.tx.camera.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.View

/**
 * create by xu.tian
 *
 * @date 2021/9/1
 */
class MyTextView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
    private var paint: Paint? = null
    init {
        initPaint()
    }
    private val text = "My TextView"
    private var width = 0f
    private var height = 0f
    private var baseLineY = 0f
    private var baseLineX = 0f
    private var textTopY = 0f
    private var textBottomY = 0f
    private var textAscentY = 0f
    private var textDescentY = 0f
    private var textLength = 0f

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawColor(Color.BLACK)
        paint!!.color = Color.YELLOW
        canvas.drawLine(baseLineX - textLength / 2, textTopY, baseLineX + textLength / 2, textTopY, paint!!)
        paint!!.color = Color.GREEN
        canvas.drawLine(baseLineX - textLength / 2, textAscentY, baseLineX + textLength / 2, textAscentY, paint!!)
        paint!!.color = Color.RED
        canvas.drawLine(baseLineX - textLength / 2, baseLineY, baseLineX + textLength / 2, baseLineY, paint!!)
        paint!!.color = Color.GREEN
        canvas.drawLine(baseLineX - textLength / 2, textDescentY, baseLineX + textLength / 2, textDescentY, paint!!)
        paint!!.color = Color.YELLOW
        canvas.drawLine(baseLineX - textLength / 2, textBottomY, baseLineX + textLength / 2, textBottomY, paint!!)
        paint!!.color = Color.WHITE
        canvas.drawText(text, baseLineX, baseLineY, paint!!)
    }

    override fun onSizeChanged(w: Int, h: Int, oldW: Int, oldH: Int) {
        super.onSizeChanged(w, h, oldW, oldH)
        width = w.toFloat()
        height = h.toFloat()
        measureTextLine()
    }

    private fun initPaint() {
        paint = Paint()
        paint!!.style = Paint.Style.FILL
        paint!!.color = Color.WHITE
        paint!!.textSize = 100f
        paint!!.strokeWidth = 5f
        // 文字的baseline以(baseLineX,baseLineY)为中点
        paint!!.textAlign = Paint.Align.CENTER
    }

    private fun measureTextLine() {
        baseLineX = width / 2
        baseLineY = height / 2
        val metrics = paint!!.fontMetrics
        textTopY = baseLineY + metrics.top
        textAscentY = baseLineY + metrics.ascent
        textDescentY = baseLineY + metrics.descent
        textBottomY = baseLineY + metrics.bottom
        Log.d(TAG, "top ---> " + metrics.top)
        Log.d(TAG, "bottom ---> " + metrics.bottom)
        Log.d(TAG, "ascent ---> " + metrics.ascent)
        Log.d(TAG, "descent ---> " + metrics.descent)
        Log.d(TAG, "leading ---> " + metrics.leading)
        textLength = paint!!.measureText(text)
    }

    companion object {
        private val TAG = MyTextView::class.java.simpleName
    }
}

运行结果

Screenshot_20210905_143227.png

Text绘制时的的几个基准线

先举例是为了更清楚的看到绘制text时的几个重要的基准线,上图运行结果中总共有5条线,它们从上至下分别是

  • top line 可绘制文字的最高基准线
  • ascent line 系统推荐的可绘制文字的最高基准线
  • base line 我们设定的参考线
  • descent line 系统推荐的可绘制文字的最低基准线
  • bottom line 可绘制文字最低基准线
    在不同的设备上会有不同的差异,像我展示的这个截图是我的虚拟机的执行结果,但在我的k30 pro上最高可绘制基准线和系统推荐的可绘制文字的最高基准线是一致的,最低可绘制基准线和系统推荐的可绘制文字的最低基准线也是一致的,因此我选择了用这个虚拟机的截图来进行说明。

绘制文字的常用方法

void drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

这里参数很容易看懂,但是这个x,y分别意味着啥呢,它就是绘制文本的基准

  • text 绘制的文本内容
  • x 基准点的x坐标
  • y 基准点的y坐标
  • paint 画笔对象

Paint设置绘制文本相关的参数

  • void setTextSize(float textSize) 设置文字大小
  • void setTextAlign(Align align) 设置文字的绘制方式
    当为Align.LEFT时,基准点就是文字的左边的点
    当为Align.CENTER时,基准点就是baseline的中心的点
    当为Align.RIGHT时,基准点就是baseline的右边的点
  • float measureText(String text) 测量需要绘制的文本的长度,相关的方法还有几个,但是都是差不多的,有兴趣可以看一下

获取文本的几条重要基准线的参数值

val metrics = paint!!.fontMetrics
Log.d(TAG, "top ---> " + metrics.top)
Log.d(TAG, "bottom ---> " + metrics.bottom)
Log.d(TAG, "ascent ---> " + metrics.ascent)
Log.d(TAG, "descent ---> " + metrics.descent)
Log.d(TAG, "leading ---> " + metrics.leading)

除了baseline是我们定义的,其他的几个参考线都是通过我们设置的文字大小来变化的,所以我们在绘制时一定要记住我们绘制文字的基准线是baseline而不是我们的文字框的最底端,记住这一点在我们绘制文字居中是非常有用的。

总结

今天的绘制文字就总结到这里吧,下篇再学别的有意思的~

相关文章

网友评论

      本文标题:Android自定义View(8) 《绘制文本》

      本文链接:https://www.haomeiwen.com/subject/oaujwltx.html