自定义view笔记汇总

一、通常在自定义view的时候我们都会继承view,并实现view的三个构造函数,例如:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {
    private int mColor = Color.RED;
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleView(Context context) {
        super(context);
        init();
    }

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

    public CircleView(Context context,AttributeSet attrs,int defStyleAttr) {
        super(context,attrs,defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
        mColor = a.getColor(R.styleable.CircleView_circle_color,Color.RED);
        a.recycle();
        init();
    }

关于三个构造函数使用时机的说法,如下:

⑴、在代码中直接new一个CircleView实例的时候,会调用第一个构造函数

⑵、在xml布局中调用CircleView的时候,会调用第二个构造函数

⑶、在xml布局文件中调用CircleView,并且CircleView标签中还有自定义属性时,调用的还是第二个构造函数

也就是说,系统默认只会调用CircleView的前两个构造函数,至于第三个构造函数的调用,通常是我们自己在构造函数中主动调用的(例如,在第二个构造函数中调用第三个构造函数)

至于自定义属性的获取,通常是在构造函数中通过obtainStyledAttributes函数实现的

二、直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时自身的大小,否则在布局中使用wrap_content就相当于使用match_parent。原因的话需要分析源码方可得知。设置的代码如下(以200px为例):

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200,200);
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200,heightSpecSize);
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize,200);
        }
    }

三、Canvas.drawCircle()方法的解析

语法:

public void drawCircle (float cx, float cy, float radius, Paint paint)

参数:

  • cx:圆心的x坐标
  • cy:圆心的y坐标
  • radius:圆的半径
  • paint:绘制时所使用的画笔

猜你喜欢

转载自blog.csdn.net/weixin_42146999/article/details/82146015