Android自定义组件之TextView

接触Android有一段时间了,但是一直都不会自定义控件。以前也写过一些,但是效果不是太显著,有些效果让我自己写我还是写不出来了。所以现在我要重头写自定义组件,我认为我现在写不出来有以下几个原因
1.对Android系统提供的一些方法接触的还是不够深刻。
2.自己写的少,没有什么思路。
3.自己写的少,没有什么思路。重要的东西要说两遍。

现在先将我的写的效果图给大家奉献上来
这里写图片描述

这个效果就是Android的TextView,我再下面说一下为什么我要写这样一个Android已经提供的效果,然后我会说一下我是怎么做的

一、说一下我为什么要写这样一个Android已经提供的效果

1.首先在这个效果中练习自定义属性
2.加深对onDraw和onMeasure方法的用法
3.通过这个组件,后面有关文字的自定义控件我都可以知道怎么写

二、下来我说一下这里的实现方法

在这个过程中,我将它大致分为四个部分
1.自定义属性的实现
2.有关Android中文字绘制的一些知识
3.onDraw方法中的实现
4.onMeasure方法的实现

        一、自定属性的实现

        首先我们在Values文件夹下创建一个布局,名字可以随便取,但是一般都会以attrs来命名

        多说无益,先来看看布局中的代码,里面注释已经很全面

        布局地址Values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <!-- name 属性名称 一般是我么自定义组件的类名 -->
    <declare-styleable name="MTextView">
        <!-- name 属性名称

        format 格式: string 文字  color 颜色
                    dimension 宽高 字体大小  integer 数字
                    reference 资源(drawable)
         -->
        <attr name="darrenText" format="string"/>
        <attr name="darrenTextColor" format="color"/>
        <attr name="darrenTextSize" format="dimension"/>
        <attr name="darrenMaxLength" format="integer"/>
        <!-- background 自定义View都是继承自View , 背景是由View管理的-->
        <!--<attr name="darrenBackground" format="reference|color"/>-->

        <!-- 枚举 -->
        <attr name="darreninputType">
            <enum name="number" value="1"/>
            <enum name="text" value="2"/>
            <enum name="password" value="3"/>
        </attr>

    </declare-styleable>
</resources>

        二、有关Android中文字绘制的一些知识

先介绍一下文字的组成部分,这里我在网上借用别人的一张图
这里写图片描述

top:是指的是最高字符到baseline的值,即ascent的最大值,为负值
bottom:是指最低字符到baseline的值,即descent的最大值,为正值
baseline :基准线,我是这样理解基准线的,他才是文字的中间线。

然后在说下基准线的算法,然后我会在onDraw方法中,会具体说一下基准线的具体算法、

baseline =(bootom -top)/2 -bootom

        三、onDraw方法中的实现

        onDraw顾名思义就是绘制的意思,就是我们进行绘画,在这里可以绘画很多东西。比如:线条,文字,图片,矩形等很多形状。这里我们就是在绘制的就是文字.

        这里贴出算基准线的代码

Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
        //获取中心线到基准线的高度
        int y =(fontMetricsInt.bottom -fontMetricsInt.top)/2-fontMetricsInt.bottom;
        //计算基准线高度
        int baseLine =getHeight()/2+y;

        然后贴出绘制文字的代码

 canvas.drawText(darrenText,x,baseLine,mPaint);

        这里darrenText代表要绘制的文字,x代表轴的长度,y代表y轴的长度(一般是文字的中心,也就是基准线),mpaint画笔

        四、onMeasure方法的实现

        onMeasure代表测量,他决定了我们组件的大小。

在onMeasure中三种测量模式
AT_MOST(wrap_caontent)
EXTRALY (固定值) 针对不同的情况指定不同的宽高,wrap_content
UNSPECIFIED 不指定大小测量模式。

一般我们在进行测量的时候一般都是判断 AT_MOST,然后贴出onMeasure的代码

    //进行测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取我们设置的宽度
        int width =MeasureSpec.getSize(widthMeasureSpec);
        int height =MeasureSpec.getSize(heightMeasureSpec);
        //获取测量模式
        int widthMode =MeasureSpec.getMode(widthMeasureSpec);
        int heightMode =MeasureSpec.getMode(heightMeasureSpec);

        if(widthMode ==MeasureSpec.AT_MOST){
            Rect rect = new Rect();
            mPaint.getTextBounds(darrenText,0,darrenText.length(),rect);
            //获取宽度
            width =rect.width()+getPaddingRight()+getPaddingLeft();
        }
        if(heightMode ==MeasureSpec.AT_MOST){
            Rect rect = new Rect();
            mPaint.getTextBounds(darrenText,0,darrenText.length(),rect);
            //获取高度
            height =rect.height()+getPaddingBottom()+getPaddingTop();

        }
        //设置我们想要设置的宽和高
        setMeasuredDimension(width,height);
    }

好了今天自定义组件TextView就到这里了。
最后献上我的项目源码https://github.com/GitHubToLiao/MyTextView.git

猜你喜欢

转载自blog.csdn.net/liao5214/article/details/72455407