Vues personnalisées
Dessinez des composants d’interface personnalisés à partir de zéro. Étendez View, implémentez onMeasure et onDraw avec Canvas et Paint, définissez des attributs XML personnalisés et créez des vues composites.
Vues personnalisées est une leçon Android Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 5. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Android Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Android Academy comprend 5 leçons au total.
Pourquoi créer des vues personnalisées ?
Parfois, les vues Android intégrées ne font pas exactement ce dont vous avez besoin. Les vues personnalisées vous permettent de :
- Dessiner des formes, graphiques, anneaux de progression ou diagrammes qui n'existent pas dans le SDK
- Créer des composants d'interface de marque utilisés de manière cohérente dans toute l'application
- Combiner plusieurs vues en un seul composant réutilisable (vue composée)
- Améliorer les performances en supprimant les hiérarchies de mises en page imbriquées
Étendre View
Créez une vue personnalisée en étendant View (ou une sous-classe comme ImageView). Remplacez le constructeur requis :
class CircleProgressView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var progress: Float = 0f
set(value) {
field = value.coerceIn(0f, 100f)
invalidate() // trigger redraw
}
// onMeasure and onDraw go here
}onMeasure()
onMeasure() indique au parent quelle taille cette vue souhaite avoir. Appelez toujours setMeasuredDimension() à la fin :
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredSize = 200 // dp → pixels
val px = (desiredSize * resources.displayMetrics.density).toInt()
val width = resolveSize(px, widthMeasureSpec)
val height = resolveSize(px, heightMeasureSpec)
// Square: same width and height
val size = minOf(width, height)
setMeasuredDimension(size, size)
}Paint — l'outil de dessin
Un objet Paint contient les informations de style nécessaires au dessin (couleur, largeur du contour, anticrénelage). Créez-le une seule fois — jamais dans onDraw() :
class CircleProgressView ... : View(...) {
// Create Paint in init, not in onDraw!
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.LTGRAY
style = Paint.Style.STROKE
strokeWidth = 20f
strokeCap = Paint.Cap.ROUND
}
private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#6750A4")
style = Paint.Style.STROKE
strokeWidth = 20f
strokeCap = Paint.Cap.ROUND
}
}onDraw() — dessiner la vue
onDraw(canvas) est appelée chaque fois que la vue doit être redessinée. Utilisez le Canvas pour dessiner des formes, du texte et des bitmaps :
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = (minOf(width, height) / 2f) - 30f
// Draw background circle
canvas.drawCircle(cx, cy, radius, backgroundPaint)
// Draw progress arc
val oval = RectF(cx - radius, cy - radius, cx + radius, cy + radius)
val sweepAngle = 360f * (progress / 100f)
canvas.drawArc(oval, -90f, sweepAngle, false, progressPaint)
}invalidate() et requestLayout()
Deux méthodes permettent de déclencher une mise à jour :
invalidate()— redessine la vue (appelleonDraw). Utilisez-la lorsque le contenu change mais que la taille reste identique.requestLayout()— mesure et redessine la vue (appelle d'abordonMeasure, puisonDraw). Utilisez-la lorsque la taille de la vue change.
Attributs personnalisés (attrs.xml)
Déclarez des attributs XML personnalisés afin de configurer la vue depuis les fichiers de mise en page :
<!-- res/values/attrs.xml -->
<resources>
<declare-styleable name="CircleProgressView">
<attr name="progressColor" format="color" />
<attr name="trackColor" format="color" />
<attr name="strokeWidth" format="dimension" />
<attr name="progress" format="float" />
</declare-styleable>
</resources>Lire les attributs personnalisés
Lisez les attributs dans le constructeur à l'aide de obtainStyledAttributes :
init {
context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView).use { ta ->
progressPaint.color = ta.getColor(
R.styleable.CircleProgressView_progressColor,
Color.parseColor("#6750A4")
)
backgroundPaint.color = ta.getColor(
R.styleable.CircleProgressView_trackColor,
Color.LTGRAY
)
val sw = ta.getDimension(R.styleable.CircleProgressView_strokeWidth, 20f)
progressPaint.strokeWidth = sw
backgroundPaint.strokeWidth = sw
progress = ta.getFloat(R.styleable.CircleProgressView_progress, 0f)
}
}Utiliser la vue personnalisée en XML
Utilisez votre vue personnalisée dans le XML de mise en page avec le chemin complet de la classe et les attributs personnalisés :
<!-- In any layout XML -->
<com.example.myapp.CircleProgressView
android:id="@+id/progressView"
android:layout_width="120dp"
android:layout_height="120dp"
app:progress="65"
app:progressColor="@color/primary"
app:trackColor="@color/surface_variant"
app:strokeWidth="12dp" />
<!-- Control in code: -->
binding.progressView.progress = 75fVues composées
Une vue composée combine des vues existantes en un seul composant réutilisable. Étendez une classe de mise en page comme LinearLayout :
class SearchBarView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : LinearLayout(context, attrs) {
private val binding = ViewSearchBarBinding.inflate(LayoutInflater.from(context), this)
init {
orientation = HORIZONTAL
binding.ivSearch.setOnClickListener {
onSearchClick?.invoke(binding.etSearch.text.toString())
}
}
var onSearchClick: ((String) -> Unit)? = null
fun setHint(hint: String) { binding.etSearch.hint = hint }
}Dessiner du texte
Dessinez du texte sur un Canvas avec drawText(). Centrez-le précisément à l'aide de Paint.getFontMetrics() :
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.BLACK
textSize = 48f
textAlign = Paint.Align.CENTER
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
// Vertically center the text:
val fm = textPaint.fontMetrics
val textY = cy - (fm.ascent + fm.descent) / 2f
canvas.drawText("${progress.toInt()}%", cx, textY, textPaint)
}Vérification rapide
Quelle méthode devez-vous appeler pour redessiner votre vue personnalisée lorsque les données changent mais que la taille reste identique ?
Récapitulatif : vues personnalisées
Vous pouvez maintenant tout dessiner à l'écran :
- Étendez
Viewavec@JvmOverloads constructor onMeasure()— indiquez la taille souhaitée avecsetMeasuredDimension()Paint— définissez le style ; créez l'objet une seule fois, et non dansonDraw()onDraw(canvas)— dessinez des cercles, des arcs, du texte et des bitmapsinvalidate()pour redessiner,requestLayout()pour effectuer une nouvelle mesure- Attributs personnalisés via
attrs.xmlpour la configuration XML - Vue composée — étendez une mise en page pour combiner des vues existantes
Ensuite : donnez vie à votre interface avec les animations et les transitions.
Questions Fréquemment Posées
La leçon « Vues personnalisées » est-elle gratuite ?
Oui — le texte complet de « Vues personnalisées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Android Academy, passe à CoddyKit PRO. Le cours Android Academy comprend 5 leçons au total.
Qu'est-ce que j'apprendrai dans « Vues personnalisées » ?
Dessinez des composants d’interface personnalisés à partir de zéro. Étendez View, implémentez onMeasure et onDraw avec Canvas et Paint, définissez des attributs XML personnalisés et créez des vues co… Tu pratiques Android Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Android Academy ?
Aucune expérience préalable n'est requise. Android Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 5.
Combien de temps prend la leçon « Vues personnalisées » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Android Academy ?
Oui. Chaque leçon Android Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Notions de base de Material Design
- Thèmes et styles
- Vues personnalisées
- Animations et transitions
- Navigation inférieure et onglets