美文网首页
Paint的基本使用

Paint的基本使用

作者: echoSuny | 来源:发表于2020-06-30 01:16 被阅读0次

    绘制文字

    1.0

    绘制文字其实是使用Canvas当中的drawText()函数来绘制的:

    class UsePaint @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
    ) : View(context, attrs, defStyleAttr) {
    
        val paint: Paint
    
        init {
            paint = Paint()
            paint.color = Color.RED
            paint.textSize = sp(22).toFloat()
        }
    
        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
            canvas.drawText("hello", 50f, 200f, paint)
        }
    }
    

    在drawText()函数中有四个参数,需要说明的是第二参数 X 和第三个参数 Y。表示文字绘制的原点坐标。需要注意的是绘制文字的原点和普通view的原点是不一样的。普通view原点都是在view的左上角,而文字的原点则是在基准线上,大概是在下图中蓝色圆点位置:

    总结一下就是y表示的是基准线,x表示文字绘制的起始位置,所以一旦文字的长度确定了,就可以绘制出文字。
    其实文字的绘制也是要画一份矩形的区域绘制的,比如这样:

    在Paint类中有一个函数:setTextAlign()。这个函数的作用是来确定所要绘制文字矩形的相对位置,也就是x的位置。所需要的参数有三个取值,下面分别来感受一下区别:
    Paint.Align.LEFT

    Paint.Align.CENTER

    Paint.Align.RIGHT

    分别对应下图中x在矩形中的位置:

    默认是LEFT。当为CENTER的时候,x是矩形下条边的中心点,而绘制是在矩形当中的,故左半边就出了屏幕就看不到了。RIGHT同理,但结果是全部出去屏幕了。
    2.0

    其实在绘制文字的时候不止一条基准线,还有其他四条线,如下图所示:


    上图中从上到下一共5条线。其中第一条和最后一条为topbottom,分别表示可绘制的最高高度和最低高度所在线。第二条和第四条为ascentdescent,分别表示为绘制单个字符时,字符应当的最高高度和最低高度所在线。剩下当中的那一条就是前面提过的基准线。
    基准线是在调用drawText()函数是传入的y值决定的。剩下的4条线则可以通过FontMetrics类计算出来。
    val metrics = paint.fontMetrics // 等价于java的paint.getMetrics()
    metrics.ascent
    metrics.descent
    metrics.top
    metrics.bottom
    

    FontMetrics中的这四个属性是具体的数值,和上面图片中的四条线不是一个概念,这四个属性是通过计算得来的。
    ascent = ascent线的y坐标-baseLine的y坐标,也就是说如果直接取出来的数值是负数。同理我们可以计算其他的三个属性值的计算方式:
    descent = descent线的y坐标-baseLine的y坐标,值为正数
    top = top线的y坐标-baseLine的y坐标,值为负数
    bottom = bottom线的y坐标-baseLine的y坐标,值为正数
    知道了这个我们就可以很容易的计算出每条线的y坐标,并画出来:

            canvas.drawLine(baseX, metrics.ascent + baseY, 800f, metrics.ascent + baseY, paint)
            canvas.drawLine(baseX, metrics.descent + baseY, 800f, metrics.descent + baseY, paint)
            canvas.drawLine(baseX, metrics.top + baseY, 800f, metrics.top + baseY, paint)
            canvas.drawLine(baseX, metrics.bottom + baseY, 800f, metrics.bottom + baseY, paint)
    

    2.1

    • 1、求字符串所占区域的高度和宽度
      根据上面的知识,很容易得到字符串所占区域的高:
            val metrics = paint.fontMetrics
            val top = baseY + metrics.top
            val bottom = baseY + metrics.bottom
            val textHeight = top + bottom
    

    宽度也是很容易得到的:

            val textWidth = paint.measureText("bigpig")
    
    • 2、最小矩形
      最小矩形是通过系统函数来获取的:
    public void getTextBounds(String text, int start, int end, Rect bounds) {
    
    1. text就是要测量最小矩形的字符串
    2. start是测量的起始字符的在字符串中的索引
    3. end是要测量的字符长度
    4. bounds用于接收测量结果
      可是如果下面把这个矩形画出来却有点匪夷所思:



      上面紫色的是ToolBar,下面黑色的细长矩形就是画出来的矩形,明显位置不对,大小也不对。大小不对是因为有一部分不在屏幕内,出去了。这是因为没有给getTextBounds()传递基准线位置,系统就会默认的以(0,0)点来作为基线来获取最小矩形。所以要获取真实的矩形位置就需要手动去加上基准位置:

            val rect = Rect()
            paint.getTextBounds("bigpig", 0, 6, rect)
            rect.top = (rect.top + baseY).toInt()
            rect.bottom = (rect.bottom + baseY).toInt()
            rect.left = (rect.left + baseX).toInt()
            rect.right = (rect.right + baseX).toInt()
            canvas.drawRect(rect, paint)
    
    3.0

    Paint的一些常用函数:

    • reset() 重置画笔

    • setColor(int color) 给画笔设置颜色

    • setARGB(int a, int r, int g,int b) 设置颜色,只不过是按照A R G B分开设置

    • setAlpha (int alpha) 给画笔设置透明度

    • setStyle(Paint .Style style) 给画笔设置样式,有三种:FILL,STROKE,FILL_AND_STROKE

    • setAntiAlias(boolean aa) 设置是否抗锯齿
      下面是不开启抗锯齿的效果,方法之后就是这样的。假如开了抗锯齿,那么效果就会圆滑很多


    • setStrokeWidth(float width) 设置画笔宽度

    • setStrokeMiter (float miter) 设置画笔的倾斜度

    • setPathEffect(PathEffect effect) 设置路径样式


    • setStrokeCap(Paint.Cap cap) 设置线帽样式 有三种:ROUND、SQUARE、BUTT

            paint.strokeCap = Paint.Cap.ROUND
            canvas.drawLine(100f, 50f, 500f, 50f, paint)
            paint.strokeCap = Paint.Cap.SQUARE
            canvas.drawLine(100f, 120f, 500f, 120f, paint)
            paint.strokeCap = Paint.Cap.BUTT
            canvas.drawLine(100f, 190f, 500f, 190f, paint)
    
    • setStrokeJoin(Paint.Join join) 设置路径的转角样式,有三种:BEVEL,MITER,ROUND
            val path = Path()
            path.moveTo(100f, 100f)
            path.lineTo(450f, 100f)
            path.lineTo(100f, 300f)
            canvas.drawPath(path, paint)
    

    可以看到默认是MITER样式

    • setDither(boolean dither) 设置是否抗抖动 图像颜色在渐变的时候,会出现类似马赛克的效果,为了让色彩过度不那么生硬,于是将相邻像素之间的颜色值进行中和,以呈现一种更细腻的过度效果。
    • setTextSize(float textSize) 设置文字大小 单位为像素
    • setFakeBoldText(boolean fakeBoldText) 设置是否为粗体文字
    • setUnderlineText(boolean underlineText) 给文字设置下划线
    • setStrikeThruText(boolean strikeThruText) 设置带有删除线效果
    • setTextAlign(Paint. Align align) 设置文字绘制点位置
    • setTextScaleX(float scaleX) 设置文字水平拉伸
    • setTextSkewX(float skewX) 设置字体水平倾斜度
    • setTypeface(Typeface typeface) 设置文字样式
    • setLinearText(boolean linearText) 设置是否打开线性文本标识 文本想快速绘制出来,需要缓存起来,但是就会占用内存。如果设置为true,则不缓存,省内存,但是绘制速度会慢一些
    • setSubpixelText(boolean subpixelText) 是否打开亚像素设置来绘制文本 设置为true,可以增强文本显示清晰度,但是会消耗计算机性能,因为它是通过程序在屏幕的两个像素之间插入的非物理的像素,需要计算。

    相关文章

      网友评论

          本文标题:Paint的基本使用

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