【问题标题】:Canvas#drawBitmap is thwarting Canvas#drawPath in SurfaceViewCanvas#drawBitmap 在 SurfaceView 中阻碍 Canvas#drawPath
【发布时间】:2012-06-22 15:54:12
【问题描述】:

我有一个SurfaceView,它必须在两个位图的下方、之间或上方绘制一条路径。我正在为路径的绘制设置动画,使其看起来会增长到全尺寸。此代码工作提供我不绘制位图。

像这样指定位图(在onLayout(...) 中,以获取View 尺寸):

mFrontBitmap = Bitmap.createBitmap((int) width, (int) height, mConfig);
Canvas temp = new Canvas(mFrontBitmap);
temp.drawColor(Color.TRANSPARENT, Mode.CLEAR);

(我正在擦拭它们以免留下任何机会。)然后SurfaceView线程的run方法中的绘制代码是

if(mCurrentLayer==Layer.BACK) {
    //draw path
    if(mPath!=null)
    canvas.drawPath(mPath, mPaint);
}

canvas.drawBitmap(mBackBitmap, 0, 0, null);

if(mCurrentLayer==Layer.MIDDLE) {
    //draw path
    if(mPath!=null)
        canvas.drawPath(mPath, mPaint);
}

canvas.drawBitmap(mFrontBitmap, 0, 0, null);

if(mCurrentLayer==Layer.FRONT) {
    //draw path
    if(mPath!=null)
        canvas.drawPath(mPath, mPaint);
}

注释掉两个drawBitmap 行后,动画渲染得很好。有了它们,在动画完成之前我什么都看不到,然后路径(完整地)直接渲染到其中一个位图。我有点茫然。我查看了 LunarLander 示例,它正在渲染背景位图,所以这显然是 SurfaceView 可以 做的事情,但对我来说不会。会是什么?

【问题讨论】:

    标签: android path bitmap draw surfaceview


    【解决方案1】:

    要在每次需要位图内容时绘制,您可以在每次执行 canvas.drawPath(...) 时使用它:

    mpath.invalidate();
    

    (我假设 mpath 是视图/表面视图)。

    所以它看起来像这样:

    if(mCurrentLayer==Layer.BACK) {
        //draw path
        if(mPath!=null) {
            canvas.drawPath(mPath, mPaint);
            mPath.invalidate();
        }
    }
    
    canvas.drawBitmap(mBackBitmap, 0, 0, null);
    
    if(mCurrentLayer==Layer.MIDDLE) {
        //draw path
        if(mPath!=null) {
            canvas.drawPath(mPath, mPaint);
            mPath.invalidate();
        }
    }
    
    canvas.drawBitmap(mFrontBitmap, 0, 0, null);
    
    if(mCurrentLayer==Layer.FRONT) {
        //draw path
        if(mPath!=null) {
            canvas.drawPath(mPath, mPaint);
            mPath.invalidate();
        }
    }
    

    【讨论】:

    • mPath 实际上是一个Path 对象; Path 中没有 invalidate() 方法。 SurfaceView 有一个SurfaceHolder,而不是像其他Views 那样从onDraw() 绘制,而是运行一个调用Canvas canvas = mSurfaceHolder.lockCanvas() 的线程,它可以让你在Canvas 对象上绘制;然后最后你调用mSurfaceHolder.unlockCanvasAndPost(canvas) (据说)将画布放到表面。因此,您不需要invalidate(),但无论如何谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多