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 est semblable à 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 remplir les conditions suivantes:

  • respecter les normes Android ;
  • Fournissez des attributs personnalisables personnalisés compatibles avec les mises en page XML Android.
  • Envoyer des événements d'accessibilité
  • Être compatible avec de nombreuses plates-formes Android

Le framework Android fournit un ensemble de classes de base et de balises XML pour vous aider à créer une vue répondant à 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 la section 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. Vous pouvez également 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 qui accepte les objets Context et 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 un View intégré à votre interface utilisateur, spécifiez-le dans un élément XML et contrôlez son apparence et son comportement à l'aide d'attributs d'élément. Vous pouvez aussi ajouter des vues personnalisées et leur appliquer un style à 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 explique comment récupérer et appliquer les 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é personnalisables nommée PieChart. Par convention, le nom de l'entité personnalisables est le même que le nom de la classe qui définit la vue personnalisée. Bien qu'il ne soit pas nécessaire de suivre cette convention, de nombreux éditeurs de code courants dépendent de cette convention d'attribution de noms pour fournir la complétion d'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'être associés à 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 de devoir répéter l'URI d'espace de noms long, l'exemple utilise une instruction 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 davantage avec le nom de la classe externe de la vue. Par exemple, la classe PieChart comporte 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 les valeurs directement à partir de AttributeSet, cette opération présente certains 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 qui sont déjà déréférencées et stylisées.

Le compilateur de ressources Android effectue une grande partie de votre travail pour faciliter l'appel de obtainStyledAttributes(). Pour chaque ressource <declare-styleable> du répertoire res/, la valeur R.java générée définit à la fois un tableau d'ID d'attributs et un ensemble de constantes qui définissent l'index de 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 des ressources partagées 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 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 le comportement fiable de la vue. Vous devez invalider la vue après toute modification de ses propriétés susceptible de changer 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 modification de propriété est susceptible d'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 les é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 ou le comportement visible de votre vue personnalisée.

Conception pour l'accessibilité

Votre vue personnalisée doit prendre en charge un large éventail d'utilisateurs. Cela inclut les utilisateurs ayant un handicap qui les empêchent de voir ou d'utiliser un écran tactile. Pour aider les utilisateurs en situation de handicap, procédez comme suit:

  • Ajoutez 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.
  • Prenez en charge 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.