Android中FrameLayout中的分层SurfaceViews

时间:2011-02-11 04:51:03

标签: java android transparency augmented-reality surfaceview

我正在尝试为Android构建增强现实应用程序,并遇到了分层表面视图的问题。我需要一个表面视图来显示我将覆盖图形的相机预览,我需要一个表面视图来绘制我的图形。第二个表面也需要在相机预览上方绘制,但具有透明背景。在我当前的实现中,我有两个表面视图工作并按预期显示,但背景不透明,因此没有第二个表面视图的外观,绘制的图形叠加在相机预览表面视图上。怎么能实现这一目标?在搜索了大量的堆栈溢出问题以及其他论坛时,我遇到了许多与此事有关的冲突意见。有人说在Android中分层表面视图是不可能的,而有些人说这是使用不同布局的问题(FrameLayout vs. LinearLayout?)具体来说,我的实现包括两个视图:一个类,CustomCameraView,它扩展了SurfaceView,以及一个类,CustomDrawView,它还扩展了FrameLayout中包含的SurfaceView,CustomDrawView出现在CustomCameraView之后。如何将这些分层,以便CustomDrawView似乎叠加在CustomCameraView上?

2 个答案:

答案 0 :(得分:9)

我想很多人都试过这个。 Google工程师明确指出(here),您应该避免堆叠表面视图。即使有人发现了一些技巧,但它可能不兼容并会导致问题。

我认为这有三种选择,具体取决于您的要求:

  • 在Surface View顶部查看

使用Surface视图进行摄像头预览,并在其顶部堆叠视图。这种方法的缺点是,绘制“普通”视图a)较慢,b)发生在UI线程中。如果你自己实现线程,你可以绕过b)。但一般来说,如果您的叠加层包含类似UI元素或一些不需要经常更新的Drawables,那么这可能就是您的选择。

  • 在SurfaceView中执行所有操作

这将在运行时提供更好的性能和更少的开销。你只有一个SurfaceView。在SurfaceView上合成叠加层并在那里绘制所有内容。当然,您可以将两种方法结合起来。

  • 在GLSurfaceView中执行所有操作

这可能是实现真正表现的方法。如上所述,但相机视图渲染为GLSurfaceView中的OpenGL纹理。

答案 1 :(得分:2)

我使用以下方法在相机的SurfaceView上方有2个透明视图:

我的活动在onCreate()方法中设置了所有视图,我没有使用任何布局文件。它看起来如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null); //savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    cameraPreview = new CameraPreview(this);
    addContentView(cameraPreview, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    animationView = new AnimationView(this);
    addContentView(animationView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    crosslinesView = new CrosslinesView(this);
    addContentView(crosslinesView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}

cameraPreview类型为SurfaceViewanimationViewcrosslinesViews类型为View。后两种观点中的onDraw()如下:

protected void onDraw(Canvas canvas) {
    // Have the view being transparent
    canvas.drawARGB(0, 0, 0, 0);
    // Your drawing code goes here
    // ...
}
祝你好运!