欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android自定义View的开篇,实现简单的TextView

程序员文章站 2022-03-29 20:23:24
android自定义View的开篇,实现简单的TextView一、简述没有基础的同学可以先看这[自定义View简介](https://www.jianshu.com/p/653a86fe450f)二、现在我们来实现TextView1、先在values新建一个attrs.xml,然后配置自定义View的属性,2、新建ViewText继承View,实现其构造方法,三个构造方法调用时机分别时,在代码中、在布局中、布局中引用style属性时3、在布局中使用自定义的View4、获取属性5、现在到了,自定义View都会...

一、简述

随着android的不断演习,必然不可免的接触到了自定义View,自定义View显然也是android知识中的重大重组部分,本篇将带领大家走进第一个自定义的View控件的实现,TextView作为基础控件之一,相信大家都很熟悉了,现在我们就来简单的实现一个TextView。

没有基础的同学可以先看这自定义View简介

二、现在我们来实现TextView

1、先在values新建一个attrs.xml,然后配置自定义View的属性,

    <declare-styleable name="ViewText">
        <attr name="mtext"  format="string"/>
        <attr name="mTextSize"  format="dimension"/>
        <attr name="mTextColor" format="color"/>
    </declare-styleable>

分别定义了文本,大小,跟颜色,属性命名尽量不要跟原生的重复,否则可能会报错

2、新建ViewText继承View,实现其构造方法,三个构造方法调用时机分别时,在代码中、在布局中、布局中引用style属性时

public class MyTextView extends View {

    public MyTextView(Context context) {
        super(context);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

我们在自定义View时也可以这样写

public class MyTextView extends View {

    public MyTextView(Context context) {
        super(context,null);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs,0);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

让他层层调用,这样最终都会执行第三个构造方法

3、在布局中使用自定义的View


    <com.example.mystudy.MyTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:mtext="这是自定义的View"
        app:mTextColor="@color/colorAccent"
        app:mSize="15dp"
        />

4、获取属性

        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MyTextView);
        mText = typedArray.getString(R.styleable.MyTextView_mtext);
        mTextColor = typedArray.getColor(R.styleable.MyTextView_mtext,mTextColor);
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.MyTextView_mtext,mTextSize);
        typedArray.recycle();

到了这,我们就完成了自定义View的属性设置到获取了

5、现在到了,自定义View都会接触到的方法onMeasure、 onDraw,在onMeasure方法中我们需要自己实现控件的宽高的测量

        //获得测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //获得测量的大小
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //如果宽高设置为wrap_content,则需要自行测量
        if(widthMode == MeasureSpec.AT_MOST){
            //矩形
            Rect rect = new Rect();
            //测量大小
            paint.getTextBounds(mText,0,mText.length(),rect);
            width = rect.width();
        }

        if(heightMode == MeasureSpec.AT_MOST){
            Rect rect = new Rect();
            paint.getTextBounds(mText,0,mText.length(),rect);
            height = rect.height();
        }

        setMeasuredDimension(width,height);

后面我们就来到onDraw方法,绘制文本还涉及到一个基线的问题,已给出计算基线方式

        Paint.FontMetricsInt f =paint.getFontMetricsInt();
        int dy = (f.top-f.bottom)/2 - f.top;
        int BaseLine = getHeight()/2+dy;
        canvas.drawText(mText,0,BaseLine,paint);

完整代码:

public class MyTextView extends View {
    public MyTextView(Context context) {
        this(context,null);
    }

    private String mText;
    private int  textSize = 15;
    private int   mColor = Color.BLACK;
    private Paint paint;
    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        this (context, attrs,0);

    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray tppeArray = context.obtainStyledAttributes(attrs,R.styleable.MyTextView);
        mText = tppeArray.getString(R.styleable.MyTextView_mtext);
        textSize = tppeArray.getDimensionPixelSize(R.styleable.MyTextView_mTextSize,15);
        mColor = tppeArray.getColor(R.styleable.MyTextView_mTextColor,mColor);
        tppeArray.recycle();
        paint = new Paint();
        paint.setColor(mColor);
        paint.setTextSize(textSize);
        paint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获得测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //获得测量的大小
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //如果宽高设置为wrap_content,则需要自行测量
        if(widthMode == MeasureSpec.AT_MOST){
            //矩形
            Rect rect = new Rect();
            //测量大小
            paint.getTextBounds(mText,0,mText.length(),rect);
            width = rect.width();
        }

        if(heightMode == MeasureSpec.AT_MOST){
            Rect rect = new Rect();
            paint.getTextBounds(mText,0,mText.length(),rect);
            height = rect.height();
        }

        setMeasuredDimension(width,height);
    }



    @Override
    protected void onDraw(Canvas canvas) {
        Paint.FontMetricsInt f =paint.getFontMetricsInt();
        int dy = (f.top-f.bottom)/2 - f.top;
        int BaseLine = getHeight()/2+dy;
        canvas.drawText(mText,0,BaseLine,paint);
    }
}

简书地址:android自定义View的开篇,实现简单的TextView

本文地址:https://blog.csdn.net/qq_40720217/article/details/107181267