自定义view-精确控制文字绘制位置

    前言:欢迎光临我的博客:http://blog.csdn.net/wanxuedong

    今天谈一谈自定义View里面的文字绘制

    有人说可能自己是知道文字是怎么知道的,但是自己做的时候可能位置老是有一些偏移什么的,几天就来解决这些问题

    首先我们需要知道绘制文字的几个属性和方法
属性:

    Rect 关于方框的属性
    Paint 添加我们需要的一些属性,包括文字的大小,颜色,格式什么的
    canvas 画笔,我们的文字就用这个东西进行绘制
    方法:

  &nbsp;&nbsp;&nbsp;&nbsp;<font color="gren" size="3">drawText       绘制文字的方法,四个参数,第一个是要绘制的文字,第二个和第三个是要绘制文字所在的坐标,第四个是Paint
为了体现对比,我这里还多用了一个方法:
  &nbsp;&nbsp;&nbsp;&nbsp;<font color="gren" size="3">drawCircle     用来绘制圆,四个参数,第一个和第二个是绘制圆的圆形,第三个是圆的半径,第四个参数是Paint
还有个方法大家可能没怎么见过:
  &nbsp;&nbsp;&nbsp;&nbsp;<font color="gren" size="3">getTextBounds  四个参数,第一个是我们要绘制的文字,第二个参数是绘制的文字起始位置,第三个参数是长度,举个例子,我们绘制的是一个数组,里面是三个文字,那么我第二个参数是0,第三个参数是2,那意思就是从第一个文字到第二个文字,具体为什么这样呢,还得看第四个参数,第四个参数正是Rect,使用这个方法过后我们会把前三个参数合作得到的信息填充到第四个参数里面,等下代码里面会解释,Rect包括了方框的left,top,right,bottom和width,height

    今天我们要完成的效果是这样的,如图:这里写图片描述

    看起来是比较简单的,一个背景,四个圆,加四个文字,好了,开始动工.
    在开始之前呢,我们还需要了解一个东西,就是坐标问题,例如drawText方法里面的坐标,我们要先了解这个坐标具体是什么样的,给出一个图给大家看一下:这里写图片描述

    这样大家应该容易理解了吧,好,下面开始绘制文字

    我分几个步骤:

    1:建立自定义View的class类

    2:布局中放置我们的自定义视图

    3:探索位置细微变化

    4:结尾

1:建立自定义View的class类

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

/**
 * Created by Mr-x on 2017/04/06.
 */

public class Word extends View {

    //这里我们定义了方框的宽高,有人说为什么有方框呢?我们下面会把控件分成四个部分,是方形,等会下面会设置属性,方便我们观看和使用
    float rectwith;
    float rectheight;
    Paint rectpaint;

    //这里定义了我们要写的字的宽高和paint
    float wordwith;
    float wordheight;
    Paint wordpaint;

    //这里是我们要写的几个字
    String str[] = {"C", "S", "D", "N"};

    public Word(Context context, AttributeSet attrs) {
        super(context, attrs);

        //这里初始化我们的Paint
        rectpaint = new Paint();
        wordpaint = new Paint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d("number", widthMeasureSpec + "");
        Log.d("number", heightMeasureSpec + "");
        //从这里我们可以得到我们控件的宽高,为什么我们这里宽度要除以4呢,因为有四个字,我们会把控件分成四个部分,每个部分写一个字
        rectwith = getMeasuredWidth() / 4;
        rectheight = getMeasuredHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        wordpaint.setTextSize(60);
        //这里我们会循环四次,把我们的字一个个的绘制上去
        for (int i = 0; i < str.length; i++) {
            Log.d("times", i + "");
            rectpaint.setColor(Color.GRAY);
            //绘制圆形背景,灰色,注意这里的横纵坐标,横坐标是:i * rectwith + rectwith / 2,即 每次都增加四分之一个控件的宽度;在看纵坐标,直接用控件高度的一半即可,而圆半径呢,我们是可以根据实际控件的宽高比例进行控制的
            canvas.drawCircle(i * rectwith + rectwith / 2, rectheight / 2, rectwith / 2, rectpaint);
            Rect rect = new Rect();
            wordpaint.getTextBounds(str[i], 0, 1, rect);
            //这里我们把一些需要用到的数据都放到了rect里面去了
            wordpaint.setColor(Color.WHITE);
            wordwith = rect.width();
            wordheight = rect.height();
            //从这里我们可以查看我们获取到的文字的有关数据
            Log.d("datass", rect.left + "");
            Log.d("datass", rect.top + "");
            Log.d("datass", rect.right + "");
            Log.d("datass", rect.bottom + "");
            Log.d("size", rect.width() + "");
            Log.d("size", rect.height() + "");
            //开始绘制文字,横坐标我们注意,当i为0时,横坐标是方框一半的宽度,再减去文字一半的宽度,这样的话文字就会处于方框正中间了,然后每次增加四分之一个控件的宽度,每次文字就都处于方框中间了,再看纵坐标,是控件一半的高度加上文字一半的高度,为什么呢?因为我们的文字是从左下角开始绘制的
            canvas.drawText(str[i], i * rectwith +  rectwith / 2 - wordwith / 2, rectheight / 2 + wordheight / 2, wordpaint);
            Log.d("times", str[i]);
        }
    }
}

//至此,我们的自定义绘制就结束了

2:布局中放置我们的自定义视图

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <org.crazyit.ui.image.Word
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_centerInParent="true"
        android:background="#f00"/>

</RelativeLayout>

3:探索位置细微变化

    不知道同学们有木有注意到我们上面打出的Log,是不是发现了什么

    没错,我们每循环一次我们得到的left,top,right,bottom的结果都是不一样,有人问这是为什么呢,这大概是绘制存在的不可避免的误差,但是总的位置是不会有什么大的改变了,上面我们设置了wordpaint.setTextSize(60);如果我们把文字的再变大,这种误差会更大,不是都是相对来说的,所以也不存在什么大问题,这里提一下是为了解决同学们心中的疑惑。

4:结尾

    刚刚过了清明节,又没有回家,感觉不太好,希望同学们有空就回家看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值