[Android]自定义View学习(一):写一个TextView

一.基础知识:

在进入自定义View的学习前,先了解相关的知识点才能更好帮助我们去理解和掌握。自定义View可以通过不同的实现方法进行分类,有继承View的,也有继承ViewGroup的。常见控件如:Textview也属于自定义View的范畴,在后面我们会去动手实现一个TextView。

开始学习前,我们先从继承View的实现方法入手,View的绘制流程包括了以下三部分:

onMeasure:测量。包括三种模式:unSpecified,exactly,at_most。具体不同在后面再详细分析

onDraw:绘制。Canvas画布绘制效果

onTouch:触摸。涉及到不同的MotionEvent和事件分发

在自定义View中,还包括最重要的自定义属性,这部分用于配置自定义属性,如颜色,字符文本,尺寸等。能够使得自定义View充满灵活性和多样性。

效果图:

二.自定义属性:

自定义属性的一般格式,在values目录下新建一个attrs文件:

这里的CiuTextColor,CiuText和CiuTextSize就是在布局文件中引用的命名,后面的format则是自定义属性的类型。

<?xml version="1.0" encoding="utf-8"?>

<resources>

<declare-styleable name="CiuTextView">

<attr name="CiuTextColor" format="color" />

<attr name="CiuText" format="string" />

<attr name="CiuTextSize" format="dimension" />

</declare-styleable>

</resources>

Layout布局中使用:

<com.demo.customizeview.CiuTextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

app:CiuText="我的自定义CiuTextview"

app:CiuTextColor="@color/colorAccent"

app:CiuTextSize="16dp" />

小Tips:如果设置完所有东西但是在Android Studio中没有预览效果,可以clean+rebuild一下,即可看到预览效果啦。

三.完整代码:


public class CiuTextView extends View {

//设置自定义属性,Panit为画笔

    private String mText;

    private int mTextColor;

    private int mTextSize;

    private Paint mPaint;



//每个自定义View都要实现以下几个构造方法,我们一般在第三个进行初始化工作。

    public CiuTextView(Context context) {

        this(context,null);

    }



    public CiuTextView(Context context, AttributeSet attrs) {

        this(context,attrs,0);

    }



    //获取attrs文件下的自定义属性

    public CiuTextView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context,attrs,defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CiuTextView);

        mText = typedArray.getString(R.styleable.CiuTextView_CiuText);

        mTextColor = typedArray.getColor(R.styleable.CiuTextView_CiuTextColor,mTextColor);

        mTextSize = typedArray.getDimensionPixelSize(R.styleable.CiuTextView_CiuTextSize,mTextSize);

        typedArray.recycle();



        mPaint = new Paint();

        //设置抗锯齿

        mPaint.setAntiAlias(true);

        //设置字体颜色

        mPaint.setTextSize(mTextSize);

        mPaint.setColor(mTextColor);

    }



    //自定义view的测量

    @Override

    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){

    //获取自定义View 的宽高模式,即上面提到的onMeasure的三种模式。        

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);



       //如果自定义TextView的宽高是确定的话,如16dp,match_parent等则不用计算

       //如果自定义TextView的宽高给的是wrap_content,则需要计算

        int width = MeasureSpec.getSize(widthMeasureSpec);

        int height = MeasureSpec.getSize(heightMeasureSpec);

            //计算宽度 

        if(widthMode == MeasureSpec.AT_MOST){

            @SuppressLint("DrawAllocation")

            //获取自定义View的矩形区域

            Rect bounds = new Rect();
 
            //getTextBounds的参数分别表示:要测量的文字,开始位置,结束位置,以及控件矩形区域
 
            mPaint.getTextBounds(mText,0,mText.length(),bounds);

            width = bounds.width()+getPaddingLeft()+getPaddingRight();

        }

            //计算高度 

        if(heightMode == MeasureSpec.AT_MOST){

            @SuppressLint("DrawAllocation")

            Rect bounds = new Rect();

            mPaint.getTextBounds(mText,0,mText.length(),bounds);

            height = bounds.height()+getPaddingTop()+getPaddingBottom();

        }

        //设置控件宽高

        setMeasuredDimension(width,height);
    }



     //正式绘制

    @Override

    protected void onDraw(Canvas canvas){

      super.onDraw(canvas);

      //计算基线

      Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();

      int dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;

      int baselint = getHeight()/2+dy;

      //drawText参数分别为:文本,文本在屏幕左边的位置,基线baseline在屏幕的位置,画笔

      canvas.drawText(mText,getPaddingLeft(),baselint,mPaint);

    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值