7

我正在为 android 构建一个绘画应用程序。扩展 SDK 提供的 FingerPaint 应用程序示例。但是,与 FingerPaint 不同的是,我使用带有单独渲染线程的 SurfaceView 来绘制到表面。所有这些都是非常标准和直接的。工作得很好。但是,我想为绘画表面提供白色背景,所以它就像在白纸上绘画一样。默认背景为黑色。我的表面视图的线程调用视图的 onDraw() 方法。

我在这里面临的问题是,如果我为我的 SurfaceView 设置背景颜色或背景资源,那么当下次渲染视图时,这个背景会覆盖之前的表面绘制。我将用一个例子来解释这一点:

假设我将背景设置为白色。现在,应用程序启动,我的 SurfaceView 具有白色。好的,到目前为止还不错。现在,我用手指在这个表面上画了一条红色的线。这条线现在显示在白色表面上。好的。现在,这应该是一个绘画应用程序,假设我想画一辆汽车。所以,然后,我用手指画出我的第二条红线。屏幕上绘制了第二条线,但我之前绘制的第一条线消失了。也就是说,因为我为 SurfaceView 设置了一些背景,所以再次绘制了背景,从而覆盖了绘制的第一行。现在屏幕只显示绘制的第二条线。

显然,我不希望这种情况发生。当我不尝试更改背景时,代码完美运行(也就是说,两条线都显示在默认的黑色背景上,没有有效的背景)。但是当我设置一些想要的背景时,就会发生这种情况。有没有办法以某种方式获得静态背景,而不是每次都绘制?我希望只绘制一次背景,所有后续的绘图都应该这个背景上发生。我不希望 android 运行时在每次绘制我的视图时绘制背景,从而从以前的渲染中覆盖该视图上存在的所有绘图。有什么办法可以解决这个问题?

我尝试过的事情是:

  1. 在 XML 中使用 android:background 设置我的 SurfaceView 的背景颜色。

  2. 做以上,使用风格的概念。(指定样式值并在布局文件中引用它)。该样式只是将背景颜色定义为#FFFFFFFF(白色)。

  3. 将样式2设置为SurfaceView的父视图(一个RelativeLayout)。

  4. 在我的清单文件中使用 android:theme 将 2 的样式设置为整个应用程序,作为主题。

  5. 将我的 SurfaceView 的背景可绘制对象设置为纯白色的图像。

  6. 从代码中调用我的 SurfaceView 的 setBackgroundColor,this.setBackgroundColor(Color.WHITE)。

谢谢。

4

2 回答 2

2

根据android的文档

表面是 Z 顺序的,因此它位于持有其 SurfaceView 的窗口后面;SurfaceView 在其窗口中打了一个孔以显示其表面。视图层次结构将负责正确地将 SurfaceView 的任何兄弟姐妹与 Surface 合成,这些兄弟通常会出现在它的顶部。这可用于在 Surface 顶部放置按钮等叠加层,但请注意,它可能会对性能产生影响,因为每次 Surface 更改时都会执行完整的 alpha 混合合成

因此,如果您通过以下方式更改表面视图的 z 顺序:

setZOrderOnTop(true);

这将起作用,但是您不能将任何其他视图放在表面视图之上。

于 2012-03-20T02:52:22.717 回答
1

现在我还尝试将我的 SurfaceView 覆盖在另一个具有白色背景的 View 上,并将 SurfaceView 设置为完全透明。我为此使用了 FrameLayout。也就是说,一个白色背景的视图,上面覆盖着我的 SurfaceView 设置为完全透明。

这也失败了。所以现在我得出结论,SurfaceView的背景颜色是不能改变的。所以现在我放弃了 SurfaceView,并使用普通视图代替了我的绘图。到目前为止,还没有观察到任何性能损失。但是,放弃一个有效的实现感觉有点不对,只是因为 SurfaceView 不允许我改变它的背景颜色。

于 2011-12-16T09:39:03.507 回答