Créer une classe de vue

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser les mises en page dans Compose.

Une vue personnalisée bien conçue ressemble à n'importe quelle autre classe bien conçue. Il encapsule un ensemble spécifique de fonctionnalités avec une interface simple, utilise efficacement le processeur et la mémoire, etc. En plus d'être une classe bien conçue, une vue personnalisée doit:

  • sont conformes aux normes Android ;
  • Fournissez des attributs avec styles personnalisés compatibles avec les mises en page XML Android.
  • Envoyer des événements d'accessibilité.
  • Être compatibles avec plusieurs plates-formes Android

Le framework Android fournit un ensemble de classes de base et de balises XML pour vous aider à créer une vue qui répond à toutes ces exigences. Cette leçon explique comment utiliser le framework Android pour créer la fonctionnalité de base d'une classe de vue.

Pour en savoir plus, consultez Composants de la vue personnalisée.

Sous-classer une vue

Toutes les classes de vue définies dans le framework Android étendent View. Votre vue personnalisée peut également étendre directement View, ou vous pouvez gagner du temps en étendant l'une des sous-classes de vue existantes, telles que Button.

Pour permettre à Android Studio d'interagir avec votre vue, vous devez au minimum fournir un constructeur utilisant un Context et un objet AttributeSet comme paramètres. Ce constructeur permet à l'éditeur de mise en page de créer et de modifier une instance de votre vue.

Kotlin

class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)

Java

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

Définir des attributs personnalisés

Pour ajouter une View intégrée à votre interface utilisateur, spécifiez-la dans un élément XML, et contrôlez son apparence et son comportement avec des attributs d'élément. Vous pouvez également ajouter des vues personnalisées et les styliser à l'aide de XML. Pour activer ce comportement dans votre vue personnalisée, procédez comme suit:

  • Définissez des attributs personnalisés pour votre vue dans un élément de ressource <declare-styleable> .
  • Spécifiez les valeurs des attributs dans votre mise en page XML.
  • Récupérez les valeurs d'attribut au moment de l'exécution.
  • Appliquez les valeurs d'attribut récupérées à votre vue.

Cette section explique comment définir des attributs personnalisés et spécifier leurs valeurs. La section suivante traite de la récupération et de l'application des valeurs au moment de l'exécution.

Pour définir des attributs personnalisés, ajoutez des ressources <declare-styleable> à votre projet. Il est d'usage de placer ces ressources dans un fichier res/values/attrs.xml. Voici un exemple de fichier attrs.xml:

<resources>
   <declare-styleable name="PieChart">
       <attr name="showText" format="boolean" />
       <attr name="labelPosition" format="enum">
           <enum name="left" value="0"/>
           <enum name="right" value="1"/>
       </attr>
   </declare-styleable>
</resources>

Ce code déclare deux attributs personnalisés, showText et labelPosition, qui appartiennent à une entité stylisée nommée PieChart. Par convention, le nom de l'entité pouvant être stylisée est identique au nom de la classe qui définit la vue personnalisée. Bien qu'il ne soit pas nécessaire de respecter cette convention, de nombreux éditeurs de code populaires dépendent de cette convention d'attribution de noms pour compléter les instructions.

Une fois que vous avez défini des attributs personnalisés, vous pouvez les utiliser dans les fichiers XML de mise en page, tout comme les attributs intégrés. La seule différence réside dans le fait que vos attributs personnalisés appartiennent à un espace de noms différent. Au lieu d'appartenir à l'espace de noms http://schemas.android.com/apk/res/android, ils appartiennent à http://schemas.android.com/apk/res/[your package name]. Par exemple, voici comment utiliser les attributs définis pour PieChart:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res-auto">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

Pour éviter d'avoir à répéter l'URI d'espace de noms long, l'exemple utilise une directive xmlns. Cette directive attribue l'alias custom à l'espace de noms http://schemas.android.com/apk/res/com.example.customviews. Vous pouvez choisir n'importe quel alias pour votre espace de noms.

Notez le nom de la balise XML qui ajoute la vue personnalisée à la mise en page. Il s'agit du nom complet de la classe de la vue personnalisée. Si votre classe de vue est une classe interne, qualifiez-la avec le nom de la classe externe de la vue. Par exemple, la classe PieChart possède une classe interne appelée PieView. Pour utiliser les attributs personnalisés de cette classe, utilisez la balise com.example.customviews.charting.PieChart$PieView.

Appliquer des attributs personnalisés

Lorsqu'une vue est créée à partir d'une mise en page XML, tous les attributs de la balise XML sont lus à partir du groupe de ressources et transmis au constructeur de la vue en tant que AttributeSet. Bien qu'il soit possible de lire directement les valeurs de AttributeSet, cette opération présente quelques inconvénients:

  • Les références de ressources dans les valeurs d'attribut ne sont pas résolues.
  • Les styles ne sont pas appliqués.

Transmettez plutôt AttributeSet à obtainStyledAttributes(). Cette méthode renvoie un tableau TypedArray de valeurs déjà déréférencées et stylisées.

Le compilateur de ressources Android effectue de nombreuses opérations pour faciliter l'appel de obtainStyledAttributes(). Pour chaque ressource <declare-styleable> du répertoire res/, le R.java généré définit à la fois un tableau d'ID d'attributs et un ensemble de constantes qui définissent l'index pour chaque attribut du tableau. Utilisez les constantes prédéfinies pour lire les attributs à partir de TypedArray. Voici comment la classe PieChart lit ses attributs:

Kotlin

init {
    context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.PieChart,
            0, 0).apply {

        try {
            mShowText = getBoolean(R.styleable.PieChart_showText, false)
            textPos = getInteger(R.styleable.PieChart_labelPosition, 0)
        } finally {
            recycle()
        }
    }
}

Java

public PieChart(Context context, AttributeSet attrs) {
   super(context, attrs);
   TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs,
        R.styleable.PieChart,
        0, 0);

   try {
       mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
       textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

Notez que les objets TypedArray sont une ressource partagée et doivent être recyclés après utilisation.

Ajouter des propriétés et des événements

Les attributs sont un moyen efficace de contrôler le comportement et l'apparence des vues, mais ils ne peuvent être lus que lorsque la vue est initialisée. Pour fournir un comportement dynamique, exposez une paire getter et setter de propriété pour chaque attribut personnalisé. L'extrait de code suivant montre comment PieChart expose une propriété appelée showText:

Kotlin

fun isShowText(): Boolean {
    return mShowText
}

fun setShowText(showText: Boolean) {
    mShowText = showText
    invalidate()
    requestLayout()
}

Java

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

Notez que setShowText appelle invalidate() et requestLayout(). Ces appels sont essentiels pour garantir que la vue se comporte de manière fiable. Vous devez invalider la vue après toute modification de ses propriétés pouvant modifier son apparence, afin que le système sache qu'elle doit être redessinée. De même, vous devez demander une nouvelle mise en page si une propriété est modifiée d'une manière qui pourrait affecter la taille ou la forme de la vue. L'oubli de ces appels de méthode peut entraîner des bugs difficiles à trouver.

Les vues personnalisées doivent également être compatibles avec les écouteurs d'événements pour communiquer des événements importants. Par exemple, PieChart expose un événement personnalisé appelé OnCurrentItemChanged pour avertir les écouteurs que l'utilisateur a fait pivoter le graphique à secteurs pour se concentrer sur un nouveau secteur.

Il est facile d'oublier d'exposer les propriétés et les événements, en particulier lorsque vous êtes le seul utilisateur de la vue personnalisée. Prendre le temps de définir soigneusement l'interface de votre vue réduit les coûts de maintenance futurs. Une bonne règle à suivre consiste à toujours exposer toute propriété qui affecte l'apparence visible ou le comportement de votre vue personnalisée.

Conception pour l'accessibilité

Votre affichage personnalisé doit accepter un large éventail d'utilisateurs. Cela inclut les utilisateurs souffrant d'un handicap qui les empêche de voir ou d'utiliser un écran tactile. Pour aider les utilisateurs ayant un handicap, procédez comme suit:

  • Attribuez des libellés à vos champs de saisie à l'aide de l'attribut android:contentDescription.
  • Envoyez des événements d'accessibilité en appelant sendAccessibilityEvent(), le cas échéant.
  • Compatible avec d'autres manettes, comme un pavé directionnel ou un trackball.

Pour en savoir plus sur la création de vues accessibles, consultez Rendre les applications plus accessibles.