113 votes

Comprendre les concepts de Canvas et de Surface

J'ai du mal à comprendre le processus de dessin pour SurfaceView et donc l'ensemble Surface / Canvas / Bitmap qui est utilisé dans Android.

J'ai lu tous les articles et les pages de documentation de l'API, que j'ai pu trouver sur le site des développeurs Android, quelques tutoriels de graphiques Android, le code source de LunarLander et cette question .

Dites-moi, s'il vous plaît, lesquelles de ces affirmations sont vraies, lesquelles ne le sont pas, et pourquoi.

  1. Canvas a sa propre Bitmap qui y est attaché. Surface a sa propre Canvas qui y est attaché.
  2. Tous View de la fenêtre partagent le même Surface et partagent donc le même Canvas .
  3. SurfaceView est une sous-classe de View qui, contrairement aux autres View et les sous-classes de View elle-même, a sa propre Surface pour attirer.

Il y a également une question supplémentaire :

  • Pourquoi est-il nécessaire d'avoir un Surface s'il existe déjà une classe Canvas pour les opérations de haut niveau avec le bitmap. Donnez un exemple d'une situation où Canvas ne convient pas pour effectuer des travaux qui Surface peut faire.

220voto

hackbod Points 55292

Voici quelques définitions :

  • Une surface est un objet qui contient des pixels en cours de composition à l'écran. Chaque fenêtre que vous voyez à l'écran (une boîte de dialogue, votre activité en plein écran, la barre d'état) possède sa propre surface dans laquelle elle se dessine, et Surface Flinger les rend à l'affichage final dans leur ordre Z correct. Une surface possède généralement plus d'un tampon (généralement deux) pour effectuer un rendu à double tampon : l'application peut dessiner son prochain état d'interface utilisateur pendant que le Surface Flinger compose l'écran en utilisant le dernier tampon, sans avoir à attendre que l'application ait fini de dessiner.

  • Une fenêtre est essentiellement ce que vous pensez d'une fenêtre sur le bureau. Elle possède une surface unique dans laquelle le contenu de la fenêtre est rendu. Une application interagit avec le gestionnaire de fenêtres pour créer des fenêtres ; le gestionnaire de fenêtres crée une surface pour chaque fenêtre et la donne à l'application pour qu'elle la dessine. L'application peut dessiner ce qu'elle veut sur la surface ; pour le gestionnaire de fenêtres, il s'agit simplement d'un rectangle opaque.

  • Une vue est un élément interactif de l'interface utilisateur à l'intérieur d'une fenêtre. Une fenêtre a une seule hiérarchie de vues attachée à elle, qui fournit tout le comportement de la fenêtre. Lorsque la fenêtre doit être redessinée (par exemple parce qu'une vue s'est invalidée), cette opération est effectuée dans la surface de la fenêtre. La surface est verrouillée, ce qui renvoie un Canvas qui peut être utilisé pour y dessiner. Une traversée de dessin est effectuée dans la hiérarchie, en transmettant le Canvas à chaque vue pour qu'elle dessine sa partie de l'interface utilisateur. Une fois le dessin effectué, la surface est déverrouillée et affichée de sorte que le tampon qui vient d'être dessiné passe au premier plan pour être ensuite composé à l'écran par Surface Flinger.

  • Un SurfaceView est une implémentation spéciale de View qui crée également sa propre surface dédiée dans laquelle l'application peut directement dessiner (en dehors de la hiérarchie normale des vues, qui doivent sinon partager la surface unique de la fenêtre). La façon dont cela fonctionne est plus simple que vous ne le pensez - tout ce que SurfaceView fait, c'est demander au gestionnaire de fenêtres de créer une nouvelle fenêtre, en lui disant d'ordonner en Z cette fenêtre, soit immédiatement derrière, soit devant la fenêtre du SurfaceView, et de la positionner de façon à ce qu'elle corresponde à l'endroit où le SurfaceView apparaît dans la fenêtre qui le contient. Si la surface est placée derrière la fenêtre principale (dans l'ordre Z), le SurfaceView remplit également sa partie de la fenêtre principale avec de la transparence afin que la surface puisse être vue.

  • Un Bitmap n'est qu'une interface vers des données de pixels. Les pixels peuvent être alloués par la Bitmap elle-même lorsque vous en créez une directement, ou elle peut pointer vers des pixels qu'elle ne possède pas, comme c'est le cas en interne lorsqu'on relie un Canvas à une Surface pour dessiner. (Un Bitmap est créé et pointe vers le tampon de dessin actuel de la Surface).

N'oubliez pas non plus que, comme cela l'implique, un SurfaceView est un objet assez lourd. Si vous avez plusieurs SurfaceViews dans une interface utilisateur particulière, arrêtez-vous et demandez-vous si cela est vraiment nécessaire. Si vous en avez plus de deux, vous en avez certainement trop.

18voto

monkjack Points 4727

Un bitmap est simplement une enveloppe pour une collection de pixels. Pensez-y comme à un tableau de pixels avec quelques autres fonctions pratiques.

Le Canvas est simplement la classe qui contient toutes les méthodes de dessin. Elle est similaire à la classe Graphics de AWT/Swing si vous êtes familier avec cette dernière. Toute la logique permettant de dessiner un cercle, une boîte, etc. est contenue dans le Canvas. Un canvas dessine sur un Bitmap ou un conteneur GL ouvert, mais il n'y a aucune raison pour qu'à l'avenir il puisse être étendu à d'autres types de rasters.

SurfaceView est une vue qui contient une surface. Une surface est similaire à un bitmap (elle possède une mémoire de pixels). Je ne sais pas comment elle est implémentée mais j'imagine qu'il s'agit d'une sorte d'enveloppe de Bitmap avec des méthodes supplémentaires pour les choses qui sont directement liées à l'affichage à l'écran (c'est la raison d'être d'une surface, un Bitmap est trop générique). Vous pouvez obtenir un canevas à partir de votre surface, ce qui revient à obtenir le canevas associé au bitmap sous-jacent.

Vos questions.

1. le Canvas a son propre Bitmap qui lui est attaché. La surface a son propre Canvas attaché à elle.

Oui, un canevas fonctionne sur un Bitmap (ou un panneau GL ouvert). Surface vous donne un canevas qui fonctionne sur ce que Surface utilise pour son magasin de pixels de style Bitmap.

Toutes les vues de la fenêtre partagent la même surface et donc le même canevas.

Non. Vous pouvez avoir autant de vues de surface que vous le souhaitez.

SurfaceView est une sous-classe de View, qui, contrairement aux autres sous-classes de View et à View lui-même, possède sa propre surface dans laquelle il peut être dessiné.

Oui. Tout comme ListView est une sous-classe de View qui possède sa propre structure de données List. Chaque sous-classe de View fait quelque chose de différent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X