旋转画布后更改RectF的坐标

3
我使用这段代码来垂直绘制文本。
RectF rectF2 = new RectF();
matrix.mapRect(rectF2, bounds);
canvas.save();
canvas.rotate(90, rectF2.right, rectF2.top);
canvas.drawText(text, rectF2.left, rectF2.bottom, mTextPaint);
canvas.restore();

这很有效,但我也想改变坐标。因为后来我要点击对象并进行拖放。
现在的问题是,如下图所示,坐标被绘制成矩形。所以当我点击该矩形区域时,只能在画布上移动文本。
因此,当我旋转画布时,我也想旋转原始坐标。我尝试了matrix.setRotate,但无法实现我想要的效果。

enter image description here


代码[在此处](https://blog.stylingandroid.com/verticaltext-part-1/)可满足您的需求。它将文本旋转90度并移动边界以匹配文本。 它不处理跑马灯滚动和_TextView_的其他一些更高级方面。 [这个项目](https://github.com/yoog568/VerticalTextView/blob/master/src/com/yoog/widget/VerticalTextView.java)是另一种使用路径的替代方法。 - Cheticamp
我想要对矩阵进行操作。因此,我将保存矩阵的值以供以后使用。 - Gunaseelan
我认为这可能是情况。虽然视图负责自我测量,但它是ViewGroup根据ViewGroup的规则定位视图的。 (您没有提到使用哪个ViewGroup。)您可以尝试通过在自定义视图中重写layout()并在那里应用矩阵值来更改边界,确定新边界并调用super。另一个可能性是制作一个支持矩阵的自定义ViewGroup。 - Cheticamp
您想绘制旋转的矩形吗?还是想知道用户何时单击了文本? - Raed Mughaus
@Android_Developer 我想两者都做。 - Gunaseelan
2个回答

1
在onDraw()中,您可以使用矩阵来转换画布。 而在onTouch()中,您可以使用矩阵的逆变换屏幕坐标。
private static class MyView extends View {

    private final Paint texPaint = new Paint(){{
        setTextSize(60);
        setColor(Color.BLACK);
    }};

    private final Paint rectPaint = new Paint(){{
        setStrokeWidth(20);
        setColor(Color.RED);
        setStyle(Paint.Style.STROKE);
    }};

    private final Matrix matrix = new Matrix();

    private final RectF rect = new RectF(0, 0, 400, 150);

    public MyView(Context context) {
        super(context);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        matrix.reset();
        matrix.postRotate(45);
        matrix.postScale(1.5f, 1.5f, 0, 0);
        matrix.postTranslate(w/2, h/2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.concat(matrix);
        canvas.drawRect(rect, rectPaint);
        //Bottom line of the drawn text is at y, if you want the text to inside the rect
        // increase the y by the text height, textHeight is the textSize
        canvas.drawText("SomeText", 0, texPaint.getTextSize(), texPaint);
        canvas.restore();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_UP) {
            float x = event.getX();
            float y = event.getY();
            Toast.makeText(getContext(), isInsideRegion(x, y) ? "Inside" : "Outside", Toast.LENGTH_SHORT).show();
        }
        return true;
    }

    private boolean isInsideRegion(float x, float y) {
        Matrix invertedMatrix = new Matrix();
        if (!matrix.invert(invertedMatrix)) {
            throw new RuntimeException("Matrix can't be inverted");
        }
        float[] point = {x, y};
        invertedMatrix.mapPoints(point);
        return rect.contains(point[0], point[1]);
    }

}

谢谢,希望这个能用。顺便问一下,你能解释一下为什么我们需要执行 matrix.postScale(1.5f, 1.5f, 0, 0); 吗?1.5f 是什么意思? - Gunaseelan
1
这只是一个例子,它将使矩形增大50%。如果您只需要旋转,则无需包括它。 - Raed Mughaus
由于我没有测试过,所以我会为这个答案添加赏金,因为我希望它能够工作。 - Gunaseelan

0
嗯,如果您想在此视图中拖动对象,可能需要创建ViewGroup并将对象放置为Views。因为所有的对象都是在画布上绘制的,您无法在它们上面轻敲和拖动。
您可以旋转、平移和调整视图的大小,并拦截它们上面的触摸事件以执行拖动操作。
您的解决方案仅适用于带有文本的图像,如果我理解正确,您无法按照您的意愿进行操作。

不,我们可以使用矩阵来进行旋转、平移和缩放。 - Gunaseelan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接