Comment utiliser correctement setZOrderMediaOverlay sur Android?

Comme beaucoup d'autres, je suis en train de dessiner des objets 3D (à l'aide de GLSurfaceView) sur la prévisualisation de la caméra (à l'aide de SurfaceView), le long avec des boutons placés sur le dessus. J'ai effectivement eu un prototype de travail, mais je ne pouvais pas obtenir le onResume travail correctement. Après un curriculum vitae, GLSurfaceView reste derrière et n'est plus visible. Je sais que c'est de travailler, parce que je peux voir sur le dessin de l'amende, si je retire la SurfaceView de la mise en page.

La cible est de Nexus One, l'exécution de stock ROM 2.3.3.

Voici la mise en page 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>


Tout cela est enveloppé dans un <merge> bloc, mais pour une raison quelconque, je ne pouvais pas l'inclure dans le ci-dessus <code> inscription. Preview est la classe qui étend la classe SurfaceView et met en œuvre la prévisualisation de la caméra de la logique.

Cela fonctionne très bien lorsque l'activité de lance. Après j'ai lancer une autre activité (par exemple, en appuyant sur un des boutons) et de fin de cette activité, l'activité principale des résumés mais les objets 3D ne sont plus visibles.

J'ai trouvé cette discussion où il est mentionné que setZOrderMediaOverlay() aidera à résoudre ce z de commande en question. Aussi, le Android document pour setZOrderMediaOverlay() dit que cette fonction doit être appelée "avant de la surface d'affichage de la fenêtre conteneur est attaché à la fenêtre du gestionnaire". Je ne sais pas comment je dois interpréter cette déclaration, j'ai donc mis des instructions de débogage dans le code pour afficher la séquence des événements. Voici comment le GLSurfaceView à quoi ressemble le code:


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);
}
}

Voici la séquence des événements lors du démarrage de l'application:

GLPreview: OnResume 
GLPreview: onAttachedToWindow 
GLPreview: onWindowVisibilityChanged -> VISIBLE 
GLPreview: surfaceCreated 
GLPreview: surfaceChanged, format=1, w=800, h=480 

Donc, je suppose que setZOrderMediaOverlay() doit être appelée dans onResume() ou dans le constructeur. Cependant, j'ai essayé diverses combinaisons de setZOrderMediaOverlay() avec true ou false, dans le GLSurfaceView ou la SurfaceView classes, mais rien de tout cela a aidé avec le problème.

Je suis relativement nouveau quand il s'agit de Android de programmation. Je suis venu jusqu'à présent, mais à ce point j'ai besoin d'aide. Si quelqu'un qui a utilisé setZOrderMediaOverlay() avec succès dans ce scénario et il a obtenu le travail avec onResume() laissez-moi savoir comment cela doit être fait.

Merci beaucoup d'avance!

FWIW, voir stackoverflow.com/questions/5648221/... pour quelques notes à propos de chevauchement SurfaceViews.

OriginalL'auteur alokoko | 2011-04-25