自定义视图属性wrap_content不起作用

时间:2015-11-11 06:03:14

标签: android android-custom-view

有点难以解释,希望大家明白我的意思。

在onMeasure()上,我这样做是为了让wrap_content按预期工作。

 // Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            //Must be this size
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);
        } else {
            //Be whatever you want
            width = desiredWidth;
        }

deiredWidth需要getHeight()方法来计算

getHight()没有准备就绪,我无法从这里计算出正确的值。

那么,有没有办法从onMeasure()

获取layout_width属性的给定宽度

或者我是否误解了某些事情。

所有相关代码

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width;
    int height;

    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int desiredWidth = getTotalIndicatorWidth(getMeasuredHeight());
    int desiredHeight = DEFAULT_HEIGHT;

    // Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
        //Must be this size
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        width = Math.min(desiredWidth, widthSize);
    } else {
        //Be whatever you want
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        //Must be this size
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        height = Math.min(desiredHeight, heightSize);
    } else {
        //Be whatever you want
        height = desiredHeight;
    }

    setMeasuredDimension(width, height);
}

private int getTotalIndicatorWidth(int h) {
    int width = 0;
    int indicatorWidth = (h == 0) ? DEFAULT_HEIGHT : h;
    for (int i = 0; i < indicatorSize; i++) {
        if (i != 0) {
            width = width + indicatorSpacing + indicatorWidth;
        } else {
            width = indicatorWidth;
        }
    }
    return width;
}

@Override
protected void onDraw(Canvas canvas) {

    pen.setStyle(Paint.Style.STROKE);
    pen.setColor(indicatorColor);
    pen.setStrokeWidth(indicatorStokeWidth);
    pen.setAntiAlias(true);

    drawIndicator(canvas, indicatorSize, 1);
}

private void drawIndicator(Canvas paper, int indicatorSize, int position) {

    int indent = 0;
    int cr = (getHeight() / 2) - getPaddingTop() - getPaddingBottom() - indicatorStokeWidth;
    int cx = cr + getPaddingLeft() + indicatorStokeWidth;
    int cy = (getHeight() / 2) + getPaddingTop() - getPaddingBottom();

    for (int i = 0; i < indicatorSize; i++) {
        paper.drawCircle(cx + indent, cy, cr, pen);
        indent = (cr * 2) + (indicatorStokeWidth) + indent;
        if ((i+1) < indicatorSize) {
            indent += indicatorSpacing;
        }
    }
}

如您所见,下图显示了自定义视图的区域,即使layout_width设置为wrap_content,但它现在对我无效。

enter image description here

2 个答案:

答案 0 :(得分:0)

您说您需要访问--regex-scss=/^([A-Za-z0-9_-]*)*\.([A-Za-z0-9_-]+) *[,{]/\2/c,class,classes/ --regex-scss=/^[ \t]+\.([A-Za-z0-9_-]+) *[,{]/\1/c,class,classes/ 来计算getHeight()方法中的desiredWidth,并且onMeasure()尚未就绪。

是的,getHeight()getHeight()无法从getWidth()访问,因为这些onMeasure()height已在width中设置方法。在onMeasure()方法中,您需要致电onMeause()。您已在代码中完成此操作。

setMeasuredDimension()

setMeasuredDimension(width, height); 是您拨打width时所获得的内容,此getWidth()是您致电height时获得的内容。

因此,如果您想访问getHeight(),请改用getHeight()

答案 1 :(得分:0)

以下代码解决了我如何在layout_width处获取layout_heightonMesaure()的问题,以便在用户请求wrap_content时正确计算我的观点

public PageIndicator(Context context, AttributeSet attrs) {
    super(context, attrs);

    int[] attrsArray = new int[] {
            android.R.attr.id,              // 0
            android.R.attr.background,      // 1
            android.R.attr.layout_width,    // 2
            android.R.attr.layout_height,   // 3
    };

    TypedArray taa = context.obtainStyledAttributes(attrs, attrsArray);
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PageIndicator, 0, 0);

    try {
        indicatorColor = ta.getColor(R.styleable.PageIndicator_indicator_color, Color.WHITE);
        indicatorStokeWidth = (int) ta.getDimension(R.styleable.PageIndicator_indicator_stokeWidth, 4);
        indicatorSpacing = (int) ta.getDimension(R.styleable.PageIndicator_indicator_spacing, 5);
        indicatorSize = ta.getInteger(R.styleable.PageIndicator_indicator_size, 3);
        indicatorPosition = ta.getInteger(R.styleable.PageIndicator_indicator_startPosition, 0);

        mLayoutWidth = taa.getLayoutDimension(2, ViewGroup.LayoutParams.MATCH_PARENT);
        mLayoutHeight = taa.getLayoutDimension(3, ViewGroup.LayoutParams.MATCH_PARENT);
    } finally {
        ta.recycle();
        taa.recycle();
    }
}