【问题标题】:Custom View partially drawn in RelativeLayout在 RelativeLayout 中部分绘制的自定义视图
【发布时间】:2018-08-12 17:52:23
【问题描述】:

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

当 x = 0 和 y = 0 时(3x3 网格由另一个自定义视图绘制)

当 x = 100 且 y = 0 时

我也设置了它的onTouchListener,当我点击红线包围的区域时,它仍然触发。但是我不知道为什么 View 的 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 的根布局,那么这两种方法有什么不同吗?

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

【问题讨论】:

    标签: android android-layout view


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多