在y中使自定义视图更大

时间:2013-12-05 00:28:57

标签: android android-custom-view

我有一个自定义视图,我试图动态地在Y方向上使它更大。这是唯一不起作用的方向。如果我在自定义视图中调整任何其他变量,则矩形会以适当的方式受到影响。如果我尝试添加到bottomY,那么底部边框就会消失,并且没有任何内容可以在下方绘制。以下是视图的代码:

private class RectView extends View{

    float leftX, rightX, topY, bottomY;
    boolean isAppt;
    boolean isBeforeTime;
    boolean isSelected;
    public Paint rectPaint;
    private RectF rectangle;
    String time;

    public RectView(Context context, float _leftX, float _rightX, float _topY, float _bottomY,
            boolean _isAppt, boolean _isBeforeTime, String _time){
        super(context);
        leftX = _leftX;
        rightX = _rightX;
        topY = _topY;
        bottomY = _bottomY;
        isAppt = _isAppt;
        isBeforeTime = _isBeforeTime;
        time = _time;
        init();
    }

    private void init(){

        rectPaint = new Paint();

        if(leftX > rightX || topY > bottomY)
            Toast.makeText(context, "Incorrect", Toast.LENGTH_SHORT).show();
        MyUtility.LogD_Common("Left = " + leftX + ", Top = " + topY + ", Right = " + rightX +
                ", Bottom = " + bottomY);
        rectangle = new RectF(leftX, topY, rightX, bottomY);

        float height = bottomY;
        float width = rightX - leftX;
        MyUtility.LogD_Common("Height = " + height + ", Width = " + width);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.FILL_PARENT, (int) height);
        //params.leftMargin = (int) leftX;
        params.bottomMargin = 10;
        //params.rightMargin = 10;
        setLayoutParams(params);
    }

    protected void onDraw(Canvas canvas){
        MyUtility.LogD_Common("Right = " + rightX);
        rectangle.left = leftX;
        rectangle.right = rightX;
        rectangle.top = topY;
        rectangle.bottom = bottomY;
        if(!isSelected){
            if(isAppt){
                if(isBeforeTime)
                    rectPaint.setARGB(144, 119, 98, 95);
                else
                    rectPaint.setARGB(144, 217, 131, 121);
                //119,98,95
                rectPaint.setStyle(Style.FILL);
            }
            else{
                rectPaint.setARGB(0, 0, 0, 0);
                rectPaint.setStyle(Style.FILL);
            }
            canvas.drawRect(rectangle, rectPaint);
            if(isAppt){
                rectPaint.setColor(Color.RED);
                rectPaint.setStrokeWidth(2);
                rectPaint.setStyle(Style.STROKE);
                canvas.drawRect(rectangle, rectPaint);
            }
        }
        else{

            rectPaint.setARGB(144, 197, 227, 191);
            rectPaint.setStyle(Style.FILL);
            canvas.drawRect(rectangle, rectPaint);
            rectPaint.setColor(Color.GREEN);
            rectPaint.setStrokeWidth(2);
            rectPaint.setStyle(Style.STROKE);
            canvas.drawRect(rectangle, rectPaint);              

        }
    }

}

为什么会发生这种情况,为什么只能在正Y方向发生?

1 个答案:

答案 0 :(得分:0)

创建此对象时,请调用init(),在其中将RelativeLayout参数的高度规格设置为您定义的局部变量height

float height = bottomY;

通过这样做,你告诉父亲RelativeLayout这个视图想要正好是创建对象时bottomY的高度。

如果你为已经创建的对象增加bottomY的值,它就不再适合你在第一次创建对象时在RelativeLayout参数中定义的高度。

首先,不建议以这种方式从类内部更改LayoutParams。这使您的自定义视图不灵活。如果在类中设置了一堆RelativeLayout.LayoutParams,那么您的自定义View只能在RelativeLayout中使用。 您应该在添加视图之前在代码中设置LayoutParams。例如:

RectView rectView = new RectView(...);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
addView(rectView, params);

其次,当系统绘制添加了自定义视图的布局时,它会经历一系列步骤。在布局过程中,它会在其所有子视图(包括您的自定义视图)上调用getMeasuredWidth()getMeasuredHeight()。您应该覆盖自定义视图onMeasure()方法,并让它报告正确的视图大小。请参阅ViewGroup参考文档中示例中的onMeasure()。它比您的案例更复杂onMeasure(),但它为您提供了基本的想法。

在您的特定情况下,类似下面的内容应该可以解决问题:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = measureWidth(widthMeasureSpec);
    int height = measureHeight(heightMeasureSpec);
    setMeasuredDimension(width, height);
}

// This method calculates the Width of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureWidth(int widthMeasureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(widthMeasureSpec);
    int specSize = MeasureSpec.getSize(widthMeasureSpec);        

    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;
    } else {
        // Return the width of the rectangle
        result = rightX - leftX;
    }
    return result;
}

// This method calculates the Height of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureHeight(int heightMeasureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(heightMeasureSpec);
    int specSize = MeasureSpec.getSize(heightMeasureSpec);

    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;
    } else {
        // Return the height of the rectangle
            result = bottomY - topY;
    }
    return result;
}