Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo usar correctamente setZOrderMediaOverlay en Android?

Como muchos otros, estoy tratando de dibujar objetos 3D (usando GLSurfaceView) en la vista previa de la cámara (usando SurfaceView), junto con algunos botones colocados en la parte superior. En realidad tengo un prototipo funcionando, pero no pude conseguir que el onResume funcionara correctamente. Después de un curriculum vitae, GLSurfaceView se queda atrás y ya no es visible. Sé que está funcionando, porque puedo ver el dibujo bien si elimino SurfaceView del diseño.

El objetivo es Nexus One, corriendo stock 2.3.3 ROM.

  • ¿Cómo mostrar la barra de progreso Indeterminada cuando se pulsa el botón Actualizar en ActionBarSherlock?
  • Dibuja una curva perfecta que conecta tres puntos
  • Android Studio: Gradle: error: no se puede encontrar la variable de símbolo
  • Notificación de Android .addAction obsoleta en api 23
  • Error de ADT de Android, dx.jar no se cargó desde la carpeta SDK
  • ImageView que es un tamaño fijo, independientemente del tamaño de la imagen
  • Aquí está el diseño 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> 

    Todo esto está envuelto en un bloque <merge> , pero por alguna razón, no podría incluirlo en el listado <code> . Preview es la clase que extiende SurfaceView e implementa la lógica de previsualización de la cámara.

    Esto funciona bien cuando se inicia la actividad. Después de iniciar otra actividad (por ejemplo, presionando uno de los botones) y terminar esa actividad, la actividad principal se reanuda, pero los objetos 3D ya no son visibles.

    He encontrado esta discusión donde se menciona que setZOrderMediaOverlay() ayudará a solucionar este problema z-ordering. Además, el documento de Android para setZOrderMediaOverlay () dice que esta función debe llamarse "antes de que la ventana de contención de la vista de superficie se adjunte al gestor de ventanas". No sé cómo debo interpretar esa declaración, así que pongo declaraciones de depuración en el código para ver la secuencia de eventos. Así es como se ve el código 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); } }
    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); } } 

    Esta es la secuencia de eventos cuando inicie la aplicación:

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

    Asumí que setZOrderMediaOverlay() necesita ser llamado en onResume() o en el constructor. Sin embargo, probé varias combinaciones de setZOrderMediaOverlay() con true o false , en las GLSurfaceView o SurfaceView , pero ninguna de ellas ayudó con el problema.

    Soy relativamente nuevo cuando se trata de la programación de Android. He venido tan lejos pero en este momento necesito ayuda. Si alguien que usó setZOrderMediaOverlay() satisfactoriamente en este escenario y lo consiguió trabajando con onResume() házmelo saber cómo debe hacerse esto.

    ¡Muchas gracias por adelantado!

  • No se puede dibujar en un lienzo HTML5 con Phonegap 2.7
  • Spanning columnas con TableLayout
  • Java.lang.IllegalStateException: FirebaseApp con nombre
  • Generación del mapa de Google Clave de la API de lanzamiento
  • Tipo no coincidente: no se puede convertir de StringBuilder a String
  • GetStaticMethodId firma de método para public static MyClass myMethod ()
  • 2 Solutions collect form web for “¿Cómo usar correctamente setZOrderMediaOverlay en Android?”

    He luchado con el mismo problema durante algún tiempo, pero creo que el código de abajo ahora funciona. (Continúa funcionando después de pausar / bloquear independientemente de si la cámara está encendida o apagada).

    En primer lugar, no tengo ninguna vista, etc definido en el archivo de diseño – se crean en el código. Lo siguiente se llama desde el método onCreate () principal – Tenga en cuenta setZOrderMediaOverlay () en el augScreen.

    No he hecho nada especial en onPause () o onResume () aparte de pasar onPause () y onResume () a través de la augScreen.

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

    La respuesta de Awila_Tech me ayudó también. Utilicé un GLSurfaceView y llamé su onPause y onResume en la onPause y onResume de las actividades, pero 1 de 5 veces mi pantalla permanecía negra mientras que el onDrawFrame real fue llamado.

    Para resumir:

     public class OpenGLApp extends Activity implements GLSurfaceView.Renderer { private GLSurfaceView mGLSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView = new GLSurfaceView(this); mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8); mGLSurfaceView.setRenderer(this); mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); mGLSurfaceView.setKeepScreenOn(true); mGLSurfaceView.setDrawingCacheEnabled(true); mGLSurfaceView.setZOrderOnTop(true); setContentView(mGLSurfaceView); //... } @Override protected void onPause() { //... mGLSurfaceView.onPause(); super.onPause(); } @Override protected void onResume() { mGLSurfaceView.onResume(); //... super.onResume(); } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.