自定义View总结笔记

自定义View

自定义的构造方法

实例代码1:

//代码中直接new出来的
public CakeView(Context context) {
     this(context,null);
}
//布局中引用
public CakeView(Context context, @Nullable AttributeSet attrs) {
     super(context, attrs);
     init();
}

//布局中应用,并且带style(不常用)    
public CakeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
     this(context, attrs);
}

其中用的比较多的是一个参数和两个参数的构造函数。两个参数的构造函数的第二个参数AttributeSet是指这个自定义View的属性值,就是下面代码中的layout_width,layout_height,defultSize等属性。

实例代码2:

<com.example.CakeView
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:defultSize="200dp"/>

这些属性可以通过obtainStyledAttributes()方法来获取属性值.

实例代码3:

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecView);
        defultSize = (int) typedArray.getDimension(R.styleable.RecView_defultSize, 200);
        typedArray.recycle();

其中defultSize属性是我自定义的属性,自定义属性在res--> values 目录下新建一个命名为attrs的xml文件。

实例代码4:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RecView" >
        <attr name="defultSize" format="dimension" />
    </declare-styleable>
</resources>

上述获取属性值的代码实例中,obtainStyledAttributes()方法获取的是自定义View的属性集,再通过getDimension(...)或getBoolean(...)方法获取具体的自定义属性。获取完记得调用typedArray.recycle()回收资源,不然可能导致内存泄漏。

自定义View中重要的两个重写方法:onMeasure() 和 onDraw()介绍:

自定义View的流程是先测量(onMeasure() ),测量完成之后再绘制到屏幕上( onDraw() )

onMeasure()方法:view的测量,也就是测量View的宽高尺寸。

实例代码5:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWSize = getMySize(defultSize, widthMeasureSpec);
        mHSize = getMySize(defultSize, heightMeasureSpec);
        setMeasuredDimension(mWSize, mHSize);
    }

public int getMySize(int defultSize, int measureSpec) {
        int mSize = defultSize;
        int size = MeasureSpec.getSize(measureSpec);
        int mode = MeasureSpec.getMode(measureSpec);
        switch (mode) {
            case MeasureSpec.UNSPECIFIED:
                break;
            case MeasureSpec.AT_MOST:
                mSize = defultSize;
                break;
            case MeasureSpec.EXACTLY:
                mSize = size;
                break;
        }
        return mSize;
    }

其中onMeasure()方法中有两个参数:widthMeasureSpec,heightMeasureSpec.这两个参数是父控件传递给子view的测量要求,他们里面包含父控件传递给子view的测量模式和父控件传递给子控件的测量值,而测量模式又分为三种,如上面的实例代码:

UNSPECIFIED:指子控件想要多大就多大,RecycleView和ListView,ScrollView就是这种模式。

AT_MOST:相当于wrap_content

EXACITLY:相当于match_parent 或者是固定尺寸,如:100dp

测量模式可以通过MeasureSpec.getMode()获取,如上述代码实例。其中getSize()方法是父控件传递给子View的测量值,上述代码实例代码5的意思是:如果实例代码2中设置的宽高是固定200dp,或者是match_parent,此时view的父控件传递给子View的测量模式是EXACITLY,父控件传递给子view的测量值等于自己设置的宽高值或者是推荐值),如果代码实例2中设置的宽高为wrap_content,此时父控件传递给子view的测量模式是ATM_MOST,测量值使用自己定义的默认值。测量完成之后一定要调用setMeasuredDimension(mWSize, mHSize)方法保存测量值。

onDraw()方法:将测量完成的view绘制到屏幕上

实例代码6:

  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int r = getMeasuredWidth()/2;
        //圆心的横坐标为控件的左边起始位置加上半径
        int centerX = getLeft() + r;
        int centerY = getTop() + r;

        mPaint.setColor(Color.RED);
        canvas.drawCircle(centerX,centerY,r,mPaint);
    }

canvas是画布,mPaint是画笔,Paint最好在构造方法中创建,因为如果在onMeasure和onDraw方法都是频繁的被调用。通过paint画笔在canvas画布上绘制你需要的图形。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值