【发布时间】:2011-08-12 07:51:48
【问题描述】:
像许多其他人一样,我正在尝试在相机预览(使用 SurfaceView)上绘制 3D 对象(使用 GLSurfaceView),以及放置在顶部的一些按钮。我实际上得到了一个原型工作,但我无法让 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> 列表中。 Preview 是 SurfaceView 的扩展类,实现了相机预览逻辑。
当活动启动时,这可以正常工作。在我启动另一个活动(例如,通过按下其中一个按钮)并完成该活动后,主要活动恢复,但 3D 对象不再可见。
我找到了this discussion,其中提到setZOrderMediaOverlay() 将有助于解决这个z-ordering 问题。此外,Android document for setZOrderMediaOverlay() 表示应该在“将表面视图的包含窗口附加到窗口管理器之前”调用此函数。我不知道我应该如何解释该语句,所以我将调试语句放在代码中以查看事件顺序。 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:表面创建 GLPreview:surfaceChanged,格式=1,w=800,h=480所以我假设setZOrderMediaOverlay() 需要在onResume() 或构造函数中调用。但是,我在GLSurfaceView 或SurfaceView 类中尝试了setZOrderMediaOverlay() 与true 或false 的各种组合,但都没有解决问题。
在 Android 编程方面,我相对较新。我已经走了这么远,但在这一点上我需要一些帮助。如果有人在这种情况下成功使用 setZOrderMediaOverlay() 并让它与 onResume() 一起工作,请告诉我需要如何完成。
提前非常感谢!
【问题讨论】:
-
FWIW,请参阅 stackoverflow.com/questions/5648221/… 了解有关重叠 SurfaceView 的一些说明。
标签: android surfaceview z-order glsurfaceview