Canvas dans Android : ce que c’est, la classe Canvas et les méthodes draw

Auteur : IT Sectr Publié le : 2026-07-21 Temps de lecture : 7 min

Canvas dans Android — est une classe du package android.graphics fournissant une API pour le rendu 2D sur View. Canvas fonctionne comme une toile sur laquelle le développeur dessine des formes géométriques, du texte, des images et des chemins à l’aide de diverses méthodes draw*. Selon la Documentation des Développeurs Android (2025), Canvas est l’outil principal pour le rendu personnalisé dans Android et est utilisé avec la classe Paint pour définir les styles et les couleurs. Chaque appel onDraw() reçoit une instance Canvas prête, associée au buffer bitmap de la vue.

Points Clés

  • Canvas — une classe pour le rendu 2D dans Android, fournit les méthodes drawRect, drawCircle, drawText, drawBitmap et autres
  • Paint — une classe qui définit le style de rendu : couleur, épaisseur, remplissage, effets (ombre, dégradé)
  • onDraw(Canvas) — la méthode de View où tout le rendu s’effectue via le Canvas reçu
  • Canvas.save() et restore() — gestion de la pile de transformations pour les transformations imbriquées du système de coordonnées
  • Path — une classe pour construire des contours et des courbes arbitraires, transmise à drawPath(Path, Paint)

Qu’est-ce que Canvas dans Android

Canvas — est la classe centrale de graphiques 2D dans Android qui fournit des méthodes pour dessiner sur un plan. Chaque Canvas est lié à un Bitmap — une zone mémoire où les résultats des opérations de dessin sont enregistrés. Lorsqu’une View est redessinée, le système transmet à onDraw() un Canvas déjà associé au buffer de cette View.

Canvas fonctionne dans un système de coordonnées où (0,0) est le coin supérieur gauche, l’axe X va vers la droite, l’axe Y vers le bas. Toutes les opérations de dessin utilisent l’état actuel de Canvas, y compris la matrice de transformation, la zone de clipping et le style Paint. Selon la Documentation Android (2025), l’API Canvas comprend plus de 30 méthodes draw* pour différents types de primitives graphiques.

Canvas et l’accélération matérielle

Depuis Android 3.0 (API 11), Canvas prend en charge l’accélération matérielle via DisplayList. En mode accéléré, les opérations Canvas sont enregistrées dans une DisplayList puis exécutées sur le GPU. Cela offre un gain de performance significatif mais impose des limitations : certaines opérations Canvas (clipPath avec clip non Path) ne sont pas prises en charge en mode accéléré.

Méthodes de base de Canvas pour le rendu

Canvas fournit un ensemble de méthodes pour dessiner des primitives de base. Chaque méthode accepte des paramètres géométriques et un objet Paint qui définit le style visuel.

MéthodeObjectifExemple
drawRect()Dessine un rectanglecanvas.drawRect(10f, 10f, 100f, 100f, paint)
drawCircle()Dessine un cerclecanvas.drawCircle(50f, 50f, 30f, paint)
drawLine()Dessine une lignecanvas.drawLine(0f, 0f, 100f, 100f, paint)
drawText()Dessine du textecanvas.drawText(“Hello”, 10f, 20f, paint)
drawBitmap()Dessine une imagecanvas.drawBitmap(bitmap, 0f, 0f, paint)
drawPath()Dessine un chemin arbitrairecanvas.drawPath(path, paint)
drawOval()Dessine un ovalecanvas.drawOval(rectF, paint)
drawArc()Dessine un arc ou un secteurcanvas.drawArc(rectF, 0f, 90f, true, paint)

Chaque méthode peut être appelée dans n’importe quel ordre — Canvas dessine dans l’ordre des appels, superposant les nouveaux éléments sur les précédents. Pour les compositions complexes, on utilise la technique de rendu multicouche avec sauvegarde et restauration de l’état de Canvas.

Classe Paint : configuration des styles et effets

Paint — est la classe qui définit comment Canvas va dessiner. Sans Paint, les méthodes Canvas sont inutiles — elle définit la couleur, l’épaisseur du trait, le style de remplissage, la taille du texte, les effets (ombre, dégradé, flou) et le mode de mélange.

Paint a des propriétés clés : color (couleur), style (FILL, STROKE ou FILL_AND_STROKE), strokeWidth (épaisseur du trait), textSize (taille du texte), isAntiAlias (antialiasing), shader (dégradé ou image). Créer un objet Paint est une opération coûteuse, il doit donc être créé une fois et réutilisé.

kotlin
private val fillPaint = Paint().apply {
    color = Color.parseColor("#FF6200EE")
    style = Paint.Style.FILL
    isAntiAlias = true
}

private val strokePaint = Paint().apply {
    color = Color.WHITE
    style = Paint.Style.STROKE
    strokeWidth = 4f
    isAntiAlias = true
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    canvas.drawCircle(100f, 100f, 80f, fillPaint)
    canvas.drawCircle(100f, 100f, 80f, strokePaint)
}

Dans cet exemple, deux objets Paint sont utilisés : un pour remplir le cercle en violet, le second pour le contour blanc. Séparer le remplissage et le contour est une pratique standard qui permet un contrôle flexible de l’apparence sans recréer les objets.

Shader et dégradés

Pour les remplissages dégradés, Paint accepte un Shader — les sous-classes LinearGradient, RadialGradient, SweepGradient. Shader est lié à Paint via la méthode setShader() et définit comment la couleur change sur la zone de dessin.

Transformations de Canvas : translate, rotate, scale

Canvas prend en charge les transformations matricielles du système de coordonnées : translate() (translation), rotate() (rotation), scale() (échelle) et skew() (inclinaison). Les transformations s’accumulent : chaque appel suivant est appliqué par-dessus les précédents.

La gestion de la pile de transformations se fait via save() et restore(). save() sauvegarde l’état actuel de Canvas (matrice, clip) dans la pile, restore() restaure le dernier état sauvegardé. Entre save() et restore(), des transformations imbriquées peuvent être appliquées.

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    canvas.save() // Save initial state
    canvas.translate(100f, 100f) // Translate origin

    // First square
    canvas.drawRect(0f, 0f, 50f, 50f, fillPaint)

    canvas.save() // Save after translate
    canvas.rotate(45f, 25f, 25f) // Rotate around square center

    // Rotated square
    canvas.drawRect(0f, 0f, 50f, 50f, strokePaint)
    canvas.restore() // Restore after rotate

    canvas.restore() // Restore initial state
}

Utilisez toujours save() avant de commencer les transformations et restore() après les avoir terminées. Les paires save/restore déséquilibrées entraînent une accumulation de la matrice et un rendu incorrect des éléments suivants.

Canvas avec Bitmap et Path pour les graphiques complexes

Pour les graphiques complexes, Canvas est combiné avec Bitmap et Path. Bitmap est utilisé pour charger des images et mettre en cache les images rendues. Path est utilisé pour construire des courbes de Bézier arbitraires, des polygones et des contours complexes.

Buffer Bitmap hors écran

La technique de rendu hors écran : un Bitmap est créé, une scène complexe est dessinée dessus via un Canvas séparé, puis le Bitmap terminé est affiché dans onDraw() via drawBitmap(). Cela permet de mettre à jour des graphiques complexes sans redessiner complètement chaque image.

kotlin
private var offscreenBitmap: Bitmap? = null
private var offscreenCanvas: Canvas? = null

fun buildOffscreenScene(width: Int, height: Int) {
    offscreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    offscreenCanvas = Canvas(offscreenBitmap)

    // Render scene once
    offscreenCanvas!!.drawColor(Color.WHITE)
    drawGrid(offscreenCanvas!!)
    drawComplexShape(offscreenCanvas!!)
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    offscreenBitmap?.let { canvas.drawBitmap(it, 0f, 0f, null) }
}

Path est utilisé pour construire des contours complexes : courbes de Bézier (quadTo, cubicTo), arcs (arcTo), lignes (lineTo). Path peut être fermé (close()) pour les formes remplies ou ouvert pour les lignes. La méthode principale drawPath() combine Path et Paint pour le rendu final.

Optimisation du rendu Canvas

Les performances du rendu Canvas affectent directement les FPS de l’application. Les principaux problèmes : allocations excessives dans onDraw(), appels fréquents à invalidate() et utilisation sous-optimale de l’accélération matérielle.

Créez les objets en dehors de onDraw()

Paint, Path, Rect, RectF et autres objets doivent être créés une fois dans l’initialiseur ou la méthode setup(). Chaque allocation dans onDraw() crée une pression sur le ramasse-miettes, entraînant des micro-ralentissements. L’exception concerne les objets static ou companion object pour les objets immuables.

Utilisez clipRect() pour limiter la zone

Si la majeure partie de la View est cachée en dehors de la zone visible (par exemple, dans ScrollView), utilisez canvas.clipRect() pour limiter le rendu. L’accélération matérielle optimise alors supplémentairement le clipping des pixels invisibles.

kotlin
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    // Clip to visible area
    canvas.save()
    canvas.clipRect(scrollX, scrollY, scrollX + width, scrollY + height)

    // Render large scene
    renderScene(canvas)
    canvas.restore()
}

Utilisez View.setLayerType() avec LAYER_TYPE_HARDWARE pour les Views avec des graphiques Canvas complexes qui sont rarement mis à jour. Pour les animations fréquemment mises à jour, utilisez LAYER_TYPE_NONE pour éviter les mises à jour coûteuses de la couche matérielle. Profilez avec GPU Profile Rendering et Android Studio Profiler.

Foire Aux Questions

Peut-on créer un Canvas sans View ?

Oui, vous pouvez créer Canvas(Bitmap) — un constructeur qui accepte un Bitmap. Ceci est utilisé pour le rendu hors écran : vous dessinez sur un Bitmap, puis l’affichez via drawBitmap(). Canvas peut également être créé à partir de Surface (pour SurfaceView) ou via Picture.

Quelle est la différence entre Canvas et SurfaceView ?

Canvas — est une API pour dessiner sur View dans le thread UI. SurfaceView — est une Surface séparée qui peut être mise à jour depuis un thread d’arrière-plan via son propre Canvas (lockCanvas() / unlockCanvasAndPost()). SurfaceView est préférable pour les jeux et la vidéo.

Pourquoi Canvas ne dessine-t-il pas après une transformation ?

La raison la plus fréquente est des paires save() et restore() déséquilibrées. Si après une transformation (translate, rotate) restore() n’est pas appelé, Canvas reste dans un système de coordonnées modifié et les éléments suivants sont dessinés avec un décalage. Vérifiez vos paires save()/restore().

Comment dessiner du texte centré sur Canvas ?

Utilisez Paint.setTextAlign(Paint.Align.CENTER) pour le centrage horizontal et Paint.getTextBounds() ou Paint.descent() / ascent() pour le vertical. Centrage : canvas.drawText(texte, centerX, centerY - (ascent + descent) / 2, paint).

Canvas prend-il en charge l’animation ?

Canvas lui-même n’anime pas — il dessine seulement l’état actuel. L’animation est obtenue par des appels séquentiels à invalidate() (ou postInvalidateOnAnimation()), dessinant chaque fois une nouvelle image dans onDraw(). Pour des animations fluides, utilisez ValueAnimator ou Choreographer pour vous synchroniser avec Vsync.

Résumé

  • Canvas — la classe centrale de rendu 2D dans Android, fournit des méthodes draw* pour dessiner des primitives, du texte et des images
  • Paint — définit le style visuel (couleur, épaisseur, remplissage, shaders) ; créé une fois et réutilisé
  • save() / restore() — gestion de la pile de transformations ; chaque transformation doit être dans une paire save/restore
  • Path — construction de contours arbitraires et de courbes de Bézier pour les graphiques vectoriels complexes
  • Offscreen Bitmap — technique de mise en cache de scènes complexes via Canvas(Bitmap) pour réduire la charge sur onDraw()
  • Accélération matérielle — accélération GPU de Canvas depuis Android 3.0, impose des limitations sur certaines opérations (clipPath)
  • Profilage — GPU Profile Rendering et Android Studio Profiler sont obligatoires pour trouver les goulots d’étranglement dans onDraw()

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi