web-dev-qa-db-fra.com

Comprendre les concepts Canvas et Surface

J'ai du mal à comprendre le processus de dessin vers SurfaceView et donc l'ensemble du système 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 Android, code source de LunarLander et cette question .

Veuillez me dire lesquelles de ces affirmations sont vraies, lesquelles ne le sont pas et pourquoi.

  1. Canvas a son propre Bitmap qui lui est attaché. Surface a son propre Canvas qui lui est attaché.
  2. Tous les 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 sous-classes de View et View elle-même, a son propre Surface à dessiner.

Il y a aussi une question supplémentaire:

  • Pourquoi une classe Surface est-elle nécessaire, s'il existe déjà une Canvas pour les opérations de haut niveau avec bitmap. Donnez un exemple de situation dans laquelle Canvas ne convient pas pour effectuer un travail que Surface peut effectuer.
110
fyodorananiev

Voici quelques définitions:

  • Une surface est un objet contenant des pixels qui sont 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) a sa propre surface dans laquelle elle dessine, et Surface Flinger les restitue à l'affichage final dans leur ordre Z correct. Une surface a 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 clignotant de surface compose l'écran en utilisant le dernier tampon, sans avoir besoin d'attendre la fin de l'application dessin.

  • Une fenêtre est fondamentalement comme vous le pensez d'une fenêtre sur le bureau. Il a une seule surface 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 le dessin. L'application peut dessiner ce qu'elle veut dans la surface; pour le gestionnaire de fenêtres, ce n'est qu'un rectangle opaque.

  • Une vue est un élément d'interface utilisateur interactif à l'intérieur d'une fenêtre. Une fenêtre a une hiérarchie de vue unique qui lui est associée, qui fournit tout le comportement de la fenêtre. Chaque fois que la fenêtre doit être redessinée (par exemple parce qu'une vue s'est invalidée), cela se fait dans la surface de la fenêtre. La surface est verrouillée, ce qui renvoie un canevas qui peut être utilisé pour y dessiner. Une traversée de tracé est effectuée dans la hiérarchie, en passant le canevas vers le bas pour chaque vue afin de dessiner sa partie de l'interface utilisateur. Une fois cela fait, la Surface est déverrouillée et publiée de sorte que le tampon juste dessiné est échangé au premier plan pour être ensuite composé à l'écran par Surface Flinger.

  • Une SurfaceView est une implémentation spéciale de View qui crée également sa propre Surface dédiée pour l'application à dessiner directement (en dehors de la hiérarchie de vue normale, qui sinon doit partager la Surface unique pour la fenêtre). La façon dont cela fonctionne est plus simple que ce à quoi vous pouvez vous attendre - tout ce que SurfaceView fait est de demander au gestionnaire de fenêtres de créer une nouvelle fenêtre, de lui dire de classer cette fenêtre Z immédiatement derrière ou devant la fenêtre de SurfaceView et de la positionner pour qu'elle corresponde où le SurfaceView apparaît dans la fenêtre contenant. Si la surface est placée derrière la fenêtre principale (dans l'ordre Z), SurfaceView remplit également sa partie de la fenêtre principale avec transparence afin que la surface soit visible.

  • Un bitmap n'est qu'une interface vers certaines données de pixels. Les pixels peuvent être alloués par Bitmap lui-même lorsque vous en créez directement un, ou il peut pointer vers des pixels qu'il ne possède pas, comme ce qui se produit en interne pour accrocher un canevas à une surface pour le dessin. (Un bitmap est créé et pointé vers le tampon de dessin actuel de la surface.)

Veuillez également garder à l'esprit que, comme cela 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 presque certainement trop.

218
hackbod

A conceptual overview of Window, Surface, Canvas, and Bitmap

Voici un aperçu conceptuel très basique et simple de la façon dont l'interaction se produit entre la fenêtre, la surface, le canevas et le bitmap.
Parfois, une représentation visuelle aide beaucoup à comprendre les concepts tordus.
J'espère que ce graphique pourrait aider quelqu'un.

45
Sabeeh

Un bitmap est simplement un wrapper pour une collection de pixels. Considérez-le comme un tableau de pixels avec d'autres fonctions pratiques.

Le Canvas est simplement la classe qui contient toutes les méthodes de dessin. Elle est similaire à la classe Graphics dans AWT/Swing si vous êtes familier avec cela. Toute la logique sur la façon de dessiner un cercle, une boîte, etc. est contenue dans Canvas. Un canevas s'appuie sur un bitmap ou un conteneur ouvert GL mais il n'y a aucune raison pour qu'il puisse à l'avenir être étendu pour s'appuyer sur d'autres types de rasters.

SurfaceView est une vue qui contient une surface. Une surface est similaire à un bitmap (elle a un magasin de pixels). Je ne sais pas comment il est implémenté, mais j'imagine qu'il s'agit d'une sorte de wrapper Bitmap avec des méthodes supplémentaires pour les choses qui sont directement liées aux affichages d'écran (C'est la raison d'une surface, un Bitmap est trop générique). Vous pouvez obtenir un canevas de votre surface qui obtient vraiment le canevas associé au bitmap sous-jacent.

Vos questions.

1.Canvas a son propre Bitmap attaché. Surface a son propre canevas attaché.

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

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

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

3.SurfaceView est une sous-classe de View, qui, contrairement aux autres sous-classes de View et à View lui-même, a sa propre surface à dessiner.

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

18
monkjack