【问题标题】:android canvas uses screen origin instead of view origin after translationandroid canvas 翻译后使用屏幕原点而不是视图原点
【发布时间】:2013-04-03 09:15:53
【问题描述】:

我正在使用自定义视图和画布在屏幕上绘制对象。视图位于屏幕原点的 Y 偏移处。我想翻译画布,然后绘制一个对象。但是,当我使用 setmatrix 翻译画布时,原点会从视图原点转移到屏幕原点。根据下面的代码,应该在视图原点绘制圆圈。但是我需要在绘制圆圈时添加视图从屏幕原点的偏移量。如何达到预期的效果?

protected void onDraw(Canvas canvas) 
{           
    super.onDraw(canvas);
    canvas.drawPaint(canvasPaint);
    m_canvasMatrix.set(getMatrix());
    m_canvasMatrix.postTranslate(-100, -100);
    canvas.setMatrix(m_canvasMatrix);
    canvas.drawCircle(100, 100, 20, circlePaint);


}

【问题讨论】:

    标签: android android-canvas


    【解决方案1】:

    我不确定我是否完全理解您的问题,但我认为您想要做的只是简单地将相对翻译应用于Canvas。在这种情况下,你几乎把事情想得太难了。您需要做的就是:

    protected void onDraw(Canvas canvas) 
    { 
        canvas.save();
    
    
        canvas.translate(100, 0);
    
    
        // At this point, drawing something (such as a square) with a top-left
        // corner at 0,0 would result in a square that's drawn with its top-left
        // 100px to the right of the left bound of the View.
    
    
        ...
    
        canvas.restore();
    }
    

    【讨论】:

    • 感谢@Trevor 的快速回复。我将做大量的平移、缩放和旋转,因此想将画布状态保存在矩阵中。但是,每当我执行 canvas.SetMatrix 时,画布都会采用屏幕原点而不是我的视图原点。有什么想法吗?
    • save() 和 restore() 方法已经允许保留画布的矩阵状态,因此在 onDraw() 完成后画布最终具有完全相同的矩阵开始了。通常你不会关心画布的当前矩阵在进入onDraw() 时实际上是什么。也许您没有意识到,当您执行各种.translate() 操作等时,您实际上是在预先连接当前矩阵。
    • 谢谢@Trevor。我没有使用画布保存/恢复,但我停止使用矩阵。我不得不改变整个逻辑。非常感谢。您的指导帮助了我。
    【解决方案2】:

    问题是,一个(包括我,最初;-)直观地期望画布的初始矩阵是单位矩阵。事实上并非如此。相反,它包含从屏幕到客户端坐标的必要转换。如果您简单地设置画布的矩阵,您可以有效地消除这种转换,这就是为什么您的圆的原点位于屏幕-(0,0)。

    要避免这种情况,只需将矩阵连接到现有的画布:

    protected void onDraw(Canvas canvas) 
    {           
        super.onDraw(canvas);
        canvas.drawPaint(canvasPaint);
        m_canvasMatrix.set(getMatrix());
        m_canvasMatrix.postTranslate(-100, -100);
        canvas.concat(m_canvasMatrix); // <- !!!
        canvas.drawCircle(100, 100, 20, circlePaint);
    }
    

    给 C# 人的一句话:

    canvas.Matrix.PreConcat(myMatrix) // <- !!! WRONG !!!
    

    不行! (想一想:不会调用 Matrix 的 setter...)

    改为使用:

    Matrix tmpMatrix = canvas.Matrix;
    tmpMatrix.PreConcat(myMatrix);
    canvas.Matrix = tmpMatrix;
    

    或者简单地说:

    canvas.Concat(myMatrix);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 2016-07-31
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多