web-dev-qa-db-fra.com

Lorsqu'il est nécessaire d'exécuter invalidate () sur une vue?

Ma réponse à cette question vient d’être acceptée, mais je commence à me demander quand exactement il faut invalider () une vue et quand ce n’est pas nécessaire?

Après avoir réfléchi un peu, je me suis rendu compte que cela devrait fonctionner plus ou moins comme ceci:

  • le dessin réel de "tout" se produit après onResume()
  • en temps "libre", certaines parties de l'écran peuvent être redessinées, mais seulement celles qui étaient invalidated (et tout ce qui se trouve en dessous)

Par conséquent, il semblerait que si je change quelque chose après onResume() (par exemple, en réponse à un clic sur un bouton, je devrais invalidate() changer la View). 

Cependant, d'après ce que dit Scana dans cette question , il doit être plus complexe que cela et cela dépend parfois de la méthode utilisée.

Par exemple. si on utilise

lastClicked.setImageBitmap();

ou

lastClicked.setImageResource();

Donc, quand il est nécessaire d'exécuter invalidate () sur une vue et comment ça marche vraiment?

36
mjaskowski

Généralement, le système gère automatiquement le redimensionnement, le masquage, l’affichage et bien d'autres choses pour vos widgets, mais des problèmes surviennent parfois si le tampon sous-jacent pour les pixels dessinés ou les données de sauvegarde a changé ou est périmé (vous permutez la ressource image en vue ou l'ensemble de données brutes change). Cela est dû au fait que le système d'exploitation ne peut pas savoir que les données ont été modifiées de la même manière.

Dans les cas où vous avez affaire à un dessin, vous devez indiquer au système que ses données sous-jacentes ne sont pas en bon état avec Widget.invalidate () et que le re-dessin est mis en file d'attente sur le fil principal, comme vous le feriez. mentionné. En fonction de l'implémentation du système et de la version d'Android, les modifications apportées par le système sont suivies mais ce que je fais habituellement est de supposer que les ressources système (tableaux d'octets, tableaux de caractères, index de ressources, dessin manuel sur le contexte) ne sont pas suivies et nécessitent un invalidate et tout le reste sera traité par le système.

20
Srdjan Grubor

(Envisagez d'accepter des réponses)

En règle générale, invalidate() signifie 'redessiner à l'écran' et renvoie un appel de la méthode onDraw() de la vue. Donc, si quelque chose change et que cela doit être reflété à l'écran, vous devez appeler invalidate(). Cependant, pour les widgets intégrés, vous devez rarement, voire jamais, appeler vous-même. Lorsque vous modifiez l'état d'un widget, le code interne appelle invalidate() si nécessaire et votre modification est reflétée à l'écran. Par exemple, si vous appelez TextView.setText(), après avoir effectué beaucoup de traitement interne (le texte tiendra-t-il à l'écran, doit-il être supprimé, etc.), TextView appellera invalidate() avant le retour de setText(). De même pour d'autres widgets. 

Si vous implémentez une vue personnalisée, vous devrez appeler invalidate() chaque fois que le modèle de support change et vous devez redessiner votre vue. Il peut également être utilisé pour créer des animations simples, où vous changez d'état, puis appelez invalidate(), changez à nouveau d'état, etc. 

66
Nikolay Elenkov

J'ai eu ce problème quand je voulais dessiner un textPaint! Mon code était

    canvas.drawPaint(textPaintNumber)
    canvas.drawText("MyText", 30F, 63F, textPaintNumber)

J'ai éliminé la première charpie et le problème a été résolu

    canvas.drawText("MyText", 30F, 63F, textPaintNumber)
0
Maryam Azhdari

S'il vous plaît rappelez-vous que le dessin à l'écran est un processus fréquent, chaque fois que vous mettez à jour une vue, ce changement doit être propagé et redessiné pour le notifier correctement. invalidate() est une méthode de déclenchement qui signale le retrait de la vue pour laquelle vous souhaitez afficher les modifications.

0
Remario