Как и многие другие, я пытаюсь рисовать трехмерные объекты (используя GLSurfaceView) при предварительном просмотре камеры (используя SurfaceView) вместе с некоторыми кнопками, расположенными сверху. На самом деле я получил работающий прототип, но не смог заставить работать onResume корректно. После возобновления GLSurfaceView остается позади и больше не отображается. Я знаю, что это работает, потому что я могу видеть чертеж нормально, если я удаляю SurfaceView из макета.
Цель - Nexus One, работающий сток 2.3.3 ROM.
Вот макет XML:
</p>
<pre><code><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
и реализует логику предварительного просмотра камеры.
Это прекрасно работает, когда начинается действие. После того, как я запускаю другое действие (например, нажатием одной из кнопок) и завершаю это действие, основное действие возобновляется, но трехмерные объекты больше не отображаются.
Я нашел это обсуждение , где упоминается, что setZOrderMediaOverlay()
поможет решить эту проблему z-упорядочения. Кроме того, в документе Android для 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 -> VISIBLE
GLPreview: surfaceCreated
GLPreview: surfaceChanged, format=1, w=800, h=480
Итак, я предположил, что setZOrderMediaOverlay()
нужно вызывать либо в onResume()
, либо в конструкторе. Однако я пробовал различные комбинации setZOrderMediaOverlay()
с true
или false
в классах GLSurfaceView
или SurfaceView
, но ни одна из них не помогла решить проблему.
Я относительно новичок в программировании на Android. Я зашел так далеко, но на данный момент мне нужна помощь. Если кто-то, кто успешно использовал setZOrderMediaOverlay()
в этом сценарии и работал с onResume()
, сообщите мне, как это нужно сделать.
Заранее большое спасибо!