初识自定义View(一)

首先来看一下都需要哪些步骤:
1.res/values下创建一个attrs.xml文件用来提供自定义属性
2.在构造方法中获得这些属性
3.重写onMeasure和onDraw方法
下面我们就来看一下具体是怎么一步步来的;
我们来创建一个名为my_first_attrs的xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyFirstView">
        <attr name="textColor" format="color"></attr>
        <attr name="text" format="string"></attr>
        <attr name="textSize" format="dimension"></attr>
    </declare-styleable>
</resources>

这里面我们定义了三个属性,分别是字体颜色、文本内容和字体大小。
下面来看一下在构造方法中是怎么获取这些属性的,

//默认字体颜色
    private static final int DEFAULT_TEXT_COLOR = 0x01;
    //默认字体大小
    private static final int DEFAULT_TEXT_SIZE = 12;

    protected int mTextColor = DEFAULT_TEXT_COLOR;

    protected int mTextSize = DEFAULT_TEXT_SIZE;

    protected String mText;

    protected Paint mPaint = new Paint();//画笔

    protected Rect mBound;//文本区域

首先定义了一些常量,包括有默认的字体颜色和字体大小,文本内容,画笔以及文本内容的区域
接下来是三个构造方法

public MyFirstView(Context context) {
        this(context, null);
    }

    public MyFirstView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyFirstView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取属性
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyFirstView);
        mText = a.getString(R.styleable.MyFirstView_text);
        mTextColor = a.getColor(R.styleable.MyFirstView_textColor, DEFAULT_TEXT_COLOR);
        mTextSize = (int) a.getDimension(R.styleable.MyFirstView_textSize, DEFAULT_TEXT_SIZE);
        a.recycle();
        //定义画笔属性
        mPaint.setTextSize(mTextSize);//字体大小
        mBound = new Rect();
        mPaint.getTextBounds(mText, 0, mText.length(), mBound);//计算文本区域
    }
在构造方法中通过TypedArray来获取自定义的一些属性值,并对文本内容所占区域进行一个计算。
剩下的就是就是重写onDraw方法了
@Override
    protected void onDraw(Canvas canvas) {
        mPaint.setColor(Color.BLUE);//画布颜色
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);//left top right bottom
        mPaint.setColor(mTextColor);//文字颜色
        canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);   
    }
为了让效果看起来更明显,我们在这里首先给画布定义了一个颜色值,并绘制。
到此,我们算是初步完成了自定义View,然而,当你给控件的宽高设置wrap_content的时候会发现填充整个屏幕,这是因为我们没有重写onMeasure方法,接下来我们来看看onMeasure里面需要写些什么。
在重写onMeasure之前,我们先了解一下onMeasure中常用的一些方法和属性,MeasureSpec.getMode()方法返回的是宽高的模式,有3中模式
EXACTLY:一般是指明确了控件的大小,一般是设置有固定的宽高或者是match_parent
AT_MOST:一般是指最大可以占用的空间,一般是设置wrap_content
UNSPECIFIED:这个模式很少用到,具体的我也不太清楚。。。
 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width = 0;
        int height = 0;

        if (widthMode == MeasureSpec.EXACTLY) {
            width = getPaddingLeft() + widthSize + getPaddingRight();
        } else {
            width = getPaddingLeft() + mBound.width() + getPaddingRight();
        }

        if (heightMode == MeasureSpec.UNSPECIFIED) {
            height = getPaddingTop() + heightSize + getPaddingBottom();
        } else {
            height = getPaddingTop() + mBound.height() + getPaddingBottom();
        }

        setMeasuredDimension(width, height);
    }

这个就是我们用来重新测量控件大小的方法,如果是设置的wrap_content的属性,我们通过paddingLeft+文本区域宽+paddingRight之和赋值给控件的宽度,同理用来测量控件的高度,最后调用setMeasuredDimension(width, height);方法就可以了

源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值