像许多其他对象一样,我正在尝试在相机预览(使用SurfaceView)上绘制3D对象(使用GLSurfaceView)以及顶部放置的一些按钮。我实际上有一个可以工作的原型(prototype),但是我无法使onResume正常工作。恢复简历后,GLSurfaceView将留在后面并且不再可见。我知道它正在工作,因为如果从布局中删除SurfaceView,我可以看到绘图很好。
目标是Nexus One,其运行库存为2.3.3 ROM。
这是布局xml:
<com.example.cameratest.GLPreview
android:id="@+id/cubes"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<com.example.cameratest.Preview
android:id="@+id/camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/buttongroup"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right" android:gravity="center">
<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonClose"></Button>
<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonMode"></Button>
<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonCameraInfo"></Button>
</LinearLayout>
所有这些都包装在<merge>
块中,但是由于某些原因,我无法将其包括在上面的<code>
list 中。 Preview
是扩展SurfaceView
并实现相机预览逻辑的类。
当 Activity 启动时,这可以正常工作。在启动另一个 Activity (例如,通过按一个按钮)并完成该 Activity 后,将继续执行主要 Activity ,但3D对象不再可见。
我发现this discussion提到setZOrderMediaOverlay()
将有助于解决此z排序问题。此外,Android document for setZOrderMediaOverlay()表示应将此函数调用为“在将包含表面 View 的窗口附加到窗口管理器之前”。我不知道该如何解释该语句,因此我将debug语句放入代码中以查看事件的顺序。 GLSurfaceView
代码如下所示:public class GLPreview extends GLSurfaceView{ private static final String TAG = "GLPreview"; public GLPreview(Context context, AttributeSet attrs) { super(context, attrs); // this.setZOrderMediaOverlay(true); } public void onPause() { super.onPause(); Log.d(TAG, "GLPreview: OnPause"); } public void onResume() { // this.setZOrderMediaOverlay(true); super.onResume(); Log.d(TAG, "GLPreview: OnResume"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceCreated"); super.surfaceCreated(holder); } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Log.d(TAG, String.format("GLPreview: surfaceChanged, format=%d, w=%d, h=%d", format, w, h)); super.surfaceChanged(holder, format, w, h); } public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceDestroyed"); super.surfaceDestroyed(holder); } protected void onAttachedToWindow() { Log.d(TAG, "GLPreview: onAttachedToWindow"); super.onAttachedToWindow(); } protected void onDetachedFromWindow() { Log.d(TAG, "GLPreview: onDetachedFromWindow"); super.onDetachedFromWindow(); } protected void onWindowVisibilityChanged (int vis) { String newVisibility; switch (vis) { case View.GONE: newVisibility = "GONE"; break; case View.INVISIBLE: newVisibility = "INVISIBLE"; break; case View.VISIBLE: newVisibility = "VISIBLE"; break; default: newVisibility = String.format("Unknown constant %d", vis); } Log.d(TAG, String.format("GLPreview: onWindowVisibilityChanged -> %s", newVisibility)); super.onWindowVisibilityChanged(vis); }}
这是启动应用程序时的事件顺序:
GLPreview:OnResume
GLPreview:onAttachedToWindow
GLPreview:onWindowVisibilityChanged->可见
GLPreview:surfaceCreated
GLPreview:surfaceChanged,格式= 1,w = 800,h = 480
因此,我假设需要在setZOrderMediaOverlay()
或构造函数中调用onResume()
。但是,我在setZOrderMediaOverlay()
或true
类中尝试了false
与GLSurfaceView
或SurfaceView
的各种组合,但都无济于事。
对于Android编程,我还比较陌生。我到目前为止已经走了,但是在这一点上我需要一些帮助。如果有人在这种情况下成功使用了setZOrderMediaOverlay()
并使其与onResume()
一起使用,请告诉我该怎么做。
在此先多谢!
最佳答案
我在同一个问题上苦苦挣扎了一段时间,但相信下面的代码现在可以工作了。 (无论相机处于开启还是关闭状态,它在暂停/锁定后都可以继续工作)。
首先,我没有在布局文件中定义任何 View 等-它们是用代码创建的。从主要的onCreate()方法调用以下内容-注意augScreen上的setZOrderMediaOverlay()。
除了将onPause()和onResume()传递到augScreen之外,在onPause()或onResume()中我没有做任何特别的事情。
// 1 - Camera Preview
camScreen = new CameraPreview(this);
setContentView(camScreen, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
// 2 - 3D object display
augScreen = new AR_SurfaceView(this, getViewRange());
addContentView(augScreen, new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
augScreen.setZOrderMediaOverlay(true);
// 3 - Permanent overlay
RelativeLayout overlayScreen = new OverlayView(this);
addContentView(overlayScreen, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
overlayScreen.setVisibility(View.VISIBLE);
// 4 - UI buttons (toggleable)
uiScreen = new UserInterfaceView(this);
addContentView(uiScreen, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));