在RelativeLayout中部分绘制的自定义视图

时间:2018-03-05 05:57:10

标签: android android-layout view

我想使用自定义视图在我的活动的根布局(RelativeLayout)上绘制一个正方形。但是,当x!= 0或y!= 0时,只会部分绘制正方形。

当x = 0且y = 0时(另一个自定义视图绘制3x3网格) enter image description here

当x = 100且y = 0时

enter image description here

我也设置了它的onTouchListener,当我点击红线包围的区域时,它仍然会被触发。但我不知道为什么视图的X和Y与所示方块的X和Y不一致。

将我的视图添加到布局的代码

        PieceView view = new PieceView(this, x, y, widthOfSquare, 0xFF5DADE2);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(widthOfSquare, widthOfSquare);
        layoutParams.leftMargin = (int)x;
        layoutParams.topMargin = (int)y;
        view.setLayoutParams(layoutParams);
        rootLayout.addView(view);

我的自定义视图

public class PieceView extends View{
    private static final int strokeWidth = 5;
    private Paint paint;
    private RectF rect;

    public PieceView(Context context, float x, float y, float size, int color) {
        super(context);
        init(x, y, size, color);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int desiredWidth = (int)rect.width();
        int desiredHeight = (int)rect.height();

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

        int width;
        int 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);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(rect, paint);
    }

    private void init(float x, float y, float size, int color){
        paint = new Paint();
        rect = new RectF(x, y, x + size, y + size);
        paint.setColor(color);
        paint.setStrokeWidth(strokeWidth);
    }
}

另外,我想知道是否应该使用

layoutParams.leftMargin = (int)x;
layoutParams.topMargin = (int)y;

或者我应该使用

view.setX(x)
view.setY(y)

指定我的方块的位置。如果ViewGroup我将其添加到具有match_parent = true的RelativeLayout并且它是Activity的根布局,那么两种方法之间有不同吗?

我已经被困了几个小时,非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

事实证明问题在于坐标。在onDraw()中,canvas的坐标系是View,而不是全局坐标系。例如,如果View.x = 100,View.y = 0,那么onDraw()中的代码将在全局坐标系中绘制一个左上角为(100 + 100,0)的矩形。