Tengo un dibujo de la aplicación que toma alrededor de 2 a 5 segundos para cargar el dibujo de dibujos complicados (realiza a través de un AsyncTask). Para una mejor experiencia de usuario, durante este tiempo he flash almacenados PNG versión del dibujo que tengo desde el directorio app como una ImageView, y muestran una carga ProgressBar llamar setContentView() en la Actividad de constructor:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
    android:id="@+id/flash"
    android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@color/note_bg_white"
        android:contentDescription="@string/content_desc_flash_img"
        android:focusable="false" />
<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="6dp"
        android:paddingLeft="6dp"
    android:paddingRight="6dp"
        android:gravity="bottom|center_vertical">
        <ProgressBar 
            style="?android:attr/progressBarStyleHorizontal"
    android:id="@+id/toolbar_progress"
    android:layout_width="match_parent"
    android:layout_height="18dp"
    android:gravity="bottom|center_vertical" />
    </RelativeLayout>
</FrameLayout>

Cuando el AsyncTask es completa, me, a continuación, llamar a setContentView() de nuevo con el nuevo diseño:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">
    <com.my.package.DrawingCanvas
        android:id="@+id/canvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:background="#ffffff" />
</RelativeLayout>

Cuando yo estaba usando un simple Canvas modelo, esto funcionó a la perfección, como es la costumbre DrawingCanvas View sería dibujar el dibujo a la pantalla inicial de onDraw() antes de ser mostrado al usuario, pero que ahora con el SurfaceView con un dibujo de bucle, yo estoy viendo la brilló de diseño, a continuación, cuando el dibujo está cargado, una pantalla en negro durante aproximadamente un segundo y, después, por último, los nuevos DrawingCanvas.

Estoy asumiendo que la razón está relacionada con el tiempo de inicio del dibujo bucle de hilo, y he dejado mi dominen de onDraw() en el SurfaceView, y que se llama, pero el lienzo disponible en onDraw() no parece llamar la SurfaceView. También he tratado de establecer un fondo de color sólido en el XML por encima de la esperanza en un mínimo para mostrar un fondo blanco, pero esos no parecen afectar a tomar, incluso de la configuración de código.

Cualquier consejo o una explicación de lo que yo estoy viendo con la pantalla en negro?

EDICIÓN:

Aceptar, han confirmado que onDraw() es el dibujo de la misma tela, por lo que dejó mi sorteo ops en la esperanza de que en la inicial de la muestra de la SurfaceView, el usuario podría ver esos dibujos, como en el ordinario de la Lona de la aplicación, y cuando el hilo se había girar, se reemplazaría el Lienzo.

Sin embargo, si puedo borrar el hilo operaciones, veo el onDraw() los resultados, pero de nuevo, DESPUÉS de la pantalla en negro flash. Y si puedo quitar el onDraw() anula completamente, todavía veo el negro flash y luego veo el diseño con el fondo blanco del XML.

Así, parece que no importa qué, siempre me voy a ver la pantalla en negro, a menos que tal vez en lugar de cambiar los diseños, yo simplemente modificar los ya existentes ‘flash’ de diseño que ya está activo?

EDIT2:

Han tratado de utilizar un ViewStub para que yo pueda inflar el SurfaceView en la Vista existente después de la nota se carga, pero el mismo problema se aplica todavía. Lo más cerca que puedo decir, no es un tamaño considerable (~200 ms) retardo entre el SurfaceView constructor y la llamada a la surfaceCreated() que se ejecuta, pero no estoy seguro de que aquí es donde esta la pantalla en negro que está sucediendo, o por qué la pantalla se dibuja negro…

EDIT3:

Mi último intento por ahora incluye la SurfaceView transparente. Esto, combinado con el abandono de la disposición existente en el lugar y simplemente añadiendo al diseño a través de la ViewStub hubiera resultado en una solución de trabajo, pensé, pero aún así, para una fracción de segundo, cuando el SurfaceView se carga la pantalla parpadea en negro antes de que el SurfaceView se muestra, como transparente. Si alguien tiene otras ideas para intentar, por favor, publicarlo.

  • Algunos operación pesada en el onCreate podría dar resultados.
  • Me muestran el ‘flash’ de diseño en onCreate(), sin retraso. La demora de la pantalla en negro viene una vez que el dibujo se carga y me pongo el SurfaceView, que sólo comprende el inicio del hilo.
  • Podemos ver la fuente de su clase DrawingCanvas?
  • Por desgracia no, no puedo publicar otra cosa que pequeños fragmentos debido a restricciones legales.
InformationsquelleAutor Paul Mennega | 2012-01-07

8 Comentarios

  1. 147

    Yo creo que he encontrado la razón para el negro flash. En mi caso estoy usando un SurfaceView dentro de un Fragmento y agregar dinámicamente este fragmento a la actividad después de un poco de acción. El momento en el que me agregue el fragmento de la actividad, la pantalla parpadea de color negro. Revisé grepcode para el SurfaceView fuente y he aquí lo que he encontrado: cuando la superficie de la vista en la ventana aparece la primera vez, solicita la ventana de los parámetros de cambiar llamando a un privado IWindowSession.relayout(..) método. Este método de «da» un nuevo marco, la ventana, y la superficie de la ventana. Creo que la pantalla parpadea justo en ese momento.

    La solución es bastante sencilla: si la ventana ya se ha apropiado de los parámetros no va a actualizar todos los de la ventana de cosas y la pantalla dejará de parpadear. La solución más sencilla es añadir un 0px la altura de la llanura SurfaceView a la primera presentación de su actividad. Este va a recrear la ventana antes de que la actividad se muestra en la pantalla, y cuando el segundo diseño se continuará utilizando la ventana con los parámetros actuales. Espero que esto ayude.

    ACTUALIZACIÓN: Parece que después de años de este comportamiento es que todavía hay. Yo recomendaría usar TextureView en lugar de SurfaceView. Esto es, literalmente, una nueva aplicación de la misma cosa que no tenga este efecto secundario así como no tiene un problema de fondo negro cuando en movimiento (por ejemplo dentro de ScrollView, ViewPager, RecyclerView etc).

    • Tan loco como esta respuesta sonidos, la adición de un 0px * 0px SurfaceView en el diseño de su actividad (la actividad de la raíz de diseño), en realidad elimina el negro Intermitente de la SurfaceView en su fragmento! Lo hice y funciona perfectamente!
    • gracias, el vacío SurfaceView resuelto mi problema!
    • Esta solución eliminado algunos de los pesados, el parpadeo de la CameraPreview como se describe en la documentación – especialmente al iniciar la vista previa.
    • Bueno… la solución está sucio, pero eficaz 🙂
    • Sigue trabajando en el 2015. Eso es totalmente ridículo solución.
    • Estoy implementando el surfaceView para un MediaPlayer en el interior de un fragmento, que es parte de un fragmento de viewpager y he intentado solucionar este problema por horas. El pensamiento es el MediaPlayer de carga. Pero fue el surfaceView…maldito. Esto funciona! Genial!!!
    • Horas de intentos de optimizaciones… yo aun no se dio cuenta de que era a causa de VideoView. Pensé que mi diseño era demasiado complejo e inflando toma el tiempo suficiente para producir un parpadeo visible. Su solución ha funcionado, gracias!
    • Es estúpido que esto es necesario para corregir el parpadeo. Yo upvoted, porque esto todavía se aplica (Debe ser la correcta answet por cierto). Es un bug o algo?
    • Usted, señor, sólo obtuvo una mención de honor de la línea de comentario en un feo pieza de solución de código! Gracias!
    • lol gracias
    • Esto hace el trabajo. Sólo para agregar… Si le sucede a ser agregar dinámicamente el SurfaceView a un niño de diseño en lugar de la raíz de diseño, a continuación, el 0px llanura SurfaceView que puede agregar a su diseño de xml DEBE ser un hijo de la presentación que se agrega dinámicamente el SurfaceView a. Esperemos que tenga sentido…
    • Eres mi ídolo! Gracias hombre!!! Funciona!
    • usted salvó mi vida! Me pregunto cómo u llegado a esta solución..:-)
    • Es complicado, pero funciona. Tenido este problema con un dispositivo con Android 4.3, pero otro dispositivo con Android 6.0 está bien. Me pregunto en que versión de Google arreglado esto.
    • No es menos sucio enfoque, sólo hay que poner getWindow().setFormat(PixelFormat.TRANSLUCENT); en el host de la actividad del onCreate() de devolución de llamada antes de llamar a setContentView().
    • la solución anterior con el formato de píxel no estaba trabajando para mí en el momento cuando me encontré con este error desde la ventana en su conjunto fue recreada.

  2. 5

    Yo no haría esto con dos presentaciones diferentes.

    Trate de hacer su elemento raíz de un RelativeLayout y luego tener la SurfaceView y ImageView ser hermanos de los niños de la eso. Independientemente de lo que suceda con su roscado, etc, el ImageView, que debe ser elaborado totalmente opaco en la parte superior de la SurfaceView, por lo que no obtener un flash.

    Una vez que el subproceso de trabajo se ha cargado el dibujo y el SurfaceView puede dibujarse a sí mismo, quitar la barra de progreso y ImageView desde el punto de vista de la jerarquía.

    • Yo había intentado esto sin éxito, pero pueden volver a visitar este poco tiempo si no puedo encontrar la causa raíz de la flash.
    • Debería funcionar. Tal vez ayudaría si publicó el código de com.mi.paquete.DrawingCanvas?
    • Esto no se explica el problema, pero parece funcionar como una solución, así que la recompensa otorgada como hackbod nunca se expandió en lo que podría ser la causa de la raíz, y todo lo que he intentado relacionados con esa línea de pensamiento parece fallar.
    • Voy a crear un proyecto de demostración y de correo electrónico a usted, si me das una dirección para el envío.
    • Correo electrónico con el demo del proyecto enviado.
    • alguien puede dar un ejemplo?

  3. 2

    Supongo que estás dibujando algo pesadas código en la superficie de su vista, porque hasta donde yo sé, la superficie vista mostrará la vista completa después de dibujar todo de una sola vez. Te sugiero que primero vaya a la onDraw (), el método de superficie de ver, a continuación, establezca en el fondo de la tela, a continuación, llamar con fuerza invalida para evitar que la pantalla en negro. Agregar una condición para estar seguro de que esta fuerza invalidar sólo se llama una vez.

  4. 1

    Usted necesita para asegurarse de que onSurfaceChanged() no retorna hasta que esté completamente elaborado y publicado el contenido de la SurfaceView de la Superficie.

    • ¿Cómo puedo asegurarme de que el Surfaceview consigue completamente dibujado y publicado? ¿Qué puede causar una llamada a onSurfaceChanged() antes un post completo y dibujar? He confirmado que la Vista está llamando onSurfaceChanged() después del inicio de mi hilo, pero antes de que el dibujo de bucle ser capaz de completar la primera operación (activa en el lockCanvas() llamada?)
    • hackbod es un senior dev en el equipo Android, probablemente tenía razón. Nunca se me ocurrió tratar de sacar de onSurfaceChanged() pero es un poco obvio ahora que ella sugiere. Ella significa en su onSurfaceChanged() llamar titular.lockCanvas(), a continuación, dibuje algo, entonces llame a soporte.unlockCanvasAndPost(). Si usted tiene un marcador de posición imageview también en la vista de árbol, simplemente rellenando el surfaceview de lona con total transparencia en caso de lograr el efecto deseado (de la que no se oscurezcan).
    • Añadiendo el código de dibujo para onSurfaceChanged() no hizo nada por desgracia – sigue viendo el negro flash.
  5. 1

    Si utiliza NavigationDrawer con fragmentos de Evos solución no va a funcionar!

    Intente utilizar NavigationDrawer con Actividades en lugar de fragmentos, esto le ayudará a 100%

    Cómo implementar NavDrawer con actividades: enlace

    Otra útil enlace. (en caso de SurfaceView va a dibujar en la parte superior de SlidingMenu)

    • Bueno no se, incluso relacionadas con la navegación de cajón, es más acerca de agregar dinámicamente fragmento con la superficie interior.
  6. 0

    » el lienzo disponible en onDraw() no parecen dibujar a la SurfaceView»
    – ¿Estás seguro de que usted no cree la segunda (o tercera…) de la instancia de la Superficie a la Vista? Y algunos de ellos podrían ser negro y ser mostrado por un segundo. No veo el código aquí, así que no puedo decir seguro, pero si estuviera en mi aplicación, me gustaría comprobar por este error al principio.

  7. 0

    Yo que enfrentan el mismo problema, pero gracias por esta respuesta

    No es menos sucio enfoque, sólo hay que poner
    getWindow().setFormat(PixelFormat.TRANSLÚCIDO); en el host de la actividad
    onCreate() de devolución de llamada antes de llamar a setContentView().

  8. 0

    CrazyOrr la solución que funcionó para mí, pero era más profundo en los comentarios de la parte superior de responder por los Evos, así que aquí está de nuevo:

    No es menos sucio enfoque, sólo hay que poner
    getWindow().setFormat(PixelFormat.TRANSLÚCIDO); en el host de la actividad
    onCreate() de devolución de llamada antes de llamar a setContentView(). – CrazyOrr 5 De Mayo
    ’16 a las 7:29

    Simplemente poniendo

    getWindow().setFormat(PixelFormat.TRANSLUCENT); 

    en la actividad del onCreate() trabajó para mí.

Dejar respuesta

Please enter your comment!
Please enter your name here