自定义控件

1.自定义控件方法的理解

(1) View的测量onMeasure():这个方法主要是测量View宽度和高度。
  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

在这个方法中,可以通过MeasureSpec.getMode()和MeasureSpec.getSize()这两个方法来获取宽和高的mode、size,然后我们可以根据这个不同类型的mode来判断需要返回的size,最后将这个宽和高的size设置在setMeasureDimension()方法中,来保存自定义的宽度和高度。
关于这个mode有三种类型:

  • EXACTLY:一般是设置了明确的值或者MATCH_PARENT;(返回的一般都是size)
  • AT_MOST:子布局限制在一个最大值内,一般斗志WRAP_CONTENT;(返回的是自定义本身的size)
  • UNSPECIFIED:表示子布局想要多大就多大,这个一般很少用;
    代码如下:
 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量宽度
        int measureWidth = measureWidth(widthMeasureSpec);
        //测量高度
        int measureHeight = measureHeight(heightMeasureSpec);
        //通过setMeasuredDimension()这个方法将测量好的宽和高设置进去
        setMeasuredDimension(measureWidth, measureHeight);

    }

    /**
     * 测量高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        switch (heightMode) {
            case MeasureSpec.EXACTLY:
                result = heightSize;
                break;
            case MeasureSpec.AT_MOST:
                result = 200;
                result = Math.min(result, heightSize);
                break;
        }
        return result;
    }

    /**
     * 测量宽度
     *
     * @param widthMeasureSpec
     * @return
     */
    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        switch (widthMode) {
            case MeasureSpec.EXACTLY:
                result = widthSize;
                break;
            case MeasureSpec.AT_MOST:
                result = 200;
                result = Math.min(result, widthSize);
                break;
        }
        return result;
    }

(2) onLayout():这个方法主要是摆放子布局在父布局中的位置;主要是调用layout()方法来摆放位置。
@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

setFrame方法的作用就是将新传入的ltrb属性赋值给View,然后判断当前View大小和位置是否发生了变化并返回

(3) onDraw():这个方法主要是通过前两个得到的参数值将自定义的view在屏幕上显示出来;调用draw()方法来设置显示的位置
*getWidth()、getHeight()和getMeasuredWidth,getMeasuredHeight的区别:

getWidth()、getHeight():这个获取的是子View相对于父View的位置,只可在onLayout()方法中获取;
getMeasuredWidth,getMeasuredHeight:这个是自定义View测量后的实际值。

你可能感兴趣的:(自定义控件)