SurfaceView clignote en noir sur la charge
J'ai une application de dessin qui prend environ 2 à 5 secondes pour charger le dessin compliqué dessins (fait par l'intermédiaire d'un AsyncTask
). Pour une meilleure expérience utilisateur, pendant ce temps je flash la stockées PNG version du dessin que j'ai depuis le répertoire app comme un ImageView
, et de montrer un chargement ProgressBar
appel setContentView()
dans l'Activité de constructeur:
<?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>
Lorsque le AsyncTask
est terminé, je puis appeler setContentView()
à nouveau avec la nouvelle mise en page:
<?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>
Quand j'étais à l'aide d'un simple Canvas
modèle, cela a fonctionné parfaitement, comme c'est la coutume DrawingCanvas View
voudrais attirer le dessin à l'écran sur la première onDraw()
avant d'être présentée à l'utilisateur, mais maintenant, à l'aide de la SurfaceView
avec un dessin de la boucle, je vois l'flashé mise en page, puis lorsque le dessin est chargé, un écran noir pendant environ une seconde, puis, enfin, la nouvelle DrawingCanvas.
Je suis en supposant que la raison est liée à la durée de démarrage du dessin de la boucle de fil, et j'ai laissé mon annuler de onDraw()
dans le SurfaceView
, et elle est appelée, mais la toile disponible en onDraw()
ne semblent pas tirer à la SurfaceView
. J'ai aussi essayé de fixer un solide arrière-plan de couleur dans le fichier XML ci-dessus en espérant au minimum pour afficher un fond blanc, mais ceux qui semblent ne jamais prendre effet, même en mettant de code.
Tout conseil ou une explication de ce que je vois avec l'écran noir?
EDIT:
Ok, ont confirmé que onDraw() est le dessin de la toile même, donc quitté mon tirage ops là en espérant que sur la première affiche de la SurfaceView, l'utilisateur devrait voir ces dessins comme dans l'ordinaire de la Toile de mise en œuvre, et lorsque le dessin fil avait lancé, il serait de remplacer la Toile.
Cependant, si j'ai effacer le dessin fil des opérations, je vois le onDraw() résultats, mais encore une fois, APRÈS l'écran noir flash. Et si je supprime le onDraw() remplacer complètement, je persiste à voir dans le noir flash et puis je vois la mise en page avec le fond blanc de l'XML.
Ainsi, il ressemble à n'importe quoi, je vais toujours voir l'écran noir, sauf peut-être au lieu de passer les mises en page, j'ai simplement modifier l'existant 'flash' de mise en page qui est déjà actif?
EDIT2:
Ont essayé d'utiliser un ViewStub afin que je puisse gonfler le SurfaceView dans la Vue existante après la note est chargé, mais le même issu s'applique toujours. Aussi loin que je peux dire, il y a une importante (~200 ms) délai entre la SurfaceView constructeur et l'appel à surfaceCreated() en cours d'exécution, mais vous ne savez pas que c'est là que l'écran noir qui se passe, ou pourquoi l'écran est en cours d'élaboration pour le noir...
EDIT3:
Ma dernière tentative pour l'instant inclut la fabrication SurfaceView transparent. Ceci, combiné avec la sortie de la mise en place et de simplement ajouter à cette mise en page via le ViewStub aurait abouti à une solution de travail, je l'ai bien, mais encore, pour une fraction de seconde lorsque le SurfaceView est le chargement de l'écran clignote en noir avant la SurfaceView est montré, comme transparent. Si quelqu'un a d'autres idées à essayer, merci de les poster.
- Certaines opérations lourdes dans le onCreate pouvait donner de tels résultats.
- Je montre le 'flash' de mise en page dans onCreate(), aucun retard n'. Retard/écran noir vient une fois que le dessin est chargé et je commence le SurfaceView, ce qui implique de départ thread.
- Pouvons-nous voir la source pour votre classe DrawingCanvas?
- Malheureusement non, je ne peux pas poster autre chose que de petits fragments en raison de restrictions légales.
Vous devez vous connecter pour publier un commentaire.
Je crois que j'ai trouvé la raison de l'éclair noir. Dans mon cas, je suis à l'aide d'une SurfaceView à l'intérieur d'un Fragment et de l'ajout dynamique de ce fragment de l'activité après un peu d'action. Le moment où j'ai ajouter le fragment de l'activité, l'écran clignote en noir. J'ai vérifié grepcode pour la SurfaceView source et voici ce que j'ai trouvé: quand la surface d'affichage apparaît dans la fenêtre de la très première fois, il demande à la fenêtre des paramètres d'évolution en appelant à un privé
IWindowSession.relayout(..)
méthode. Cette méthode "donne" un nouveau cadre, d'une fenêtre et de la fenêtre de la surface. Je pense que l'écran clignote à ce moment-là.La solution est assez simple: si votre fenêtre a déjà des paramètres appropriés, il ne sera pas rafraîchir la fenêtre du stuff et de l'écran ne clignote pas. La solution la plus simple est d'ajouter un
0px
hauteur de la plaine SurfaceView de la première présentation de votre activité. Cela permettra de recréer la fenêtre avant l'activité est indiqué sur l'écran, et lorsque vous définissez votre deuxième mise en page, il va juste continuer à l'aide de la fenêtre avec les paramètres actuels. J'espère que cette aide.Mise à JOUR: Ressemble, après des années ce problème est toujours là. Je vous recommande d'utiliser TextureView au lieu de SurfaceView. C'est littéralement une nouvelle mise en œuvre de la même chose que n'ont pas d'effets secondaires ainsi que ne pas avoir un problème de fond noir lorsque vous le déplacer (par exemple dans le ScrollView, ViewPager, RecyclerView etc).
getWindow().setFormat(PixelFormat.TRANSLUCENT);
dans l'armée de l'activité onCreate() de rappel avant d'appeler setContentView().Je ne voudrais pas le faire avec deux mises en page.
Essayez de faire de votre élément racine d'un RelativeLayout et puis d'avoir le SurfaceView et ImageView être de la fratrie enfants de. Tout ce qui se passe avec votre enfilage etc, l'ImageView doit être rédigé entièrement opaque sur le dessus de la SurfaceView, de sorte que vous ne sera pas obtenir un flash.
Une fois votre thread de travail a chargé le dessin et la SurfaceView pouvez dessiner lui-même, de supprimer la barre de progression et ImageView à partir de la vue de la hiérarchie.
Je suppose que vous êtes le dessin de certains lourde de code dans votre surface d'affichage, car autant que je sache, la surface d'affichage présente l'intégralité de la vue après l'élaboration de tout un temps. Je vous suggère de d'abord aller à la onDraw() la méthode de la surface d'affichage d'arrière-plan de toile puis appeler avec force invalider pour éviter que l'écran noir. Ajouter une condition pour être sûr que cette force invalider n'est appelée qu'une seule fois.
Vous devez vous assurer que onSurfaceChanged() ne retourne pas jusqu'à ce que vous ayez complètement établi et affiché le contenu de la SurfaceView de la Surface.
onSurfaceChanged()
avant un poste complet et en tirer? J'ai confirmé que le point de Vue de l'appelant onSurfaceChanged() après le début de mon dessin thread, mais avant que le dessin de la boucle de pouvoir effectuer une première opération (déclenchée à la lockCanvas() l'appel?)onSurfaceChanged()
n'a rien fait malheureusement - toujours de voir le noir flash.Si vous utilisez NavigationDrawer avec des fragments, que Evos solution ne fonctionnera pas!
Essayez d'utiliser NavigationDrawer avec des Activités plutôt que de fragments, cela vous aidera à 100%
Comment mettre en œuvre NavDrawer avec activités: lien
Un autre utile lien. (en cas de SurfaceView s'appuiera sur le haut de SlidingMenu)
" la toile disponible en onDraw() ne semblent pas tirer à la SurfaceView"
- Êtes-vous sûr que vous ne créez pas de seconde (ou troisième...) instance de la Surface d'Affichage? Et certains d'entre eux pourraient être noir et être affiché pendant une seconde. Je ne vois pas le code ici, donc, je ne peux pas dire sûrement, mais si c'était à ma demande, je voudrais vérifier pour cette erreur au début.
J'face à la même question, mais merci pour cette réponse
CrazyOrr la solution a fonctionné pour moi, mais elle était profonde dans les commentaires pour la réponse sommet par Evos, donc, ici, il est à nouveau:
Mettant simplement
dans l'activité de
onCreate()
a fonctionné pour moi.