Créer une classe de vue

Essayez la méthode 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. Elle 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 effectuer les opérations suivantes :

  • Se conformer aux normes Android.
  • Fournir des attributs personnalisés stylables qui fonctionnent avec les mises en page XML Android.
  • Envoyer des événements d'accessibilité.
  • Être compatible 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 la section Composants de 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 View directement, 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 qui accepte un objet 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 un élément View intégré à votre interface utilisateur, spécifiez-le dans un élément XML et contrôlez son apparence et son comportement avec des attributs d'élément. Vous pouvez également ajouter et styliser des vues personnalisées à 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 <declare-styleable> élément de ressource.
  • Spécifiez des valeurs pour les attributs dans votre mise en page XML.
  • Récupérez les valeurs d'attribut lors 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 lors 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 res/values/attrs.xml fichier. 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é stylable nommée PieChart. Par convention, le nom de l'entité stylable est le même nom 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 en dépendent pour fournir la saisie semi-automatique.

Une fois que vous avez défini des attributs personnalisés, vous pouvez les utiliser dans des fichiers XML de mise en page comme des attributs intégrés. La seule différence est 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 le long URI d'espace de noms, l'exemple utilise une xmlns directive. Cette directive attribue l'alias custom à l'espace de noms http://schemas.android.com/apk/res/com.example.customviews. Vous pouvez choisir l'alias de votre choix 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 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, vous 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 bundle de ressources et transmis au constructeur de la vue en tant qu' AttributeSet. Bien qu'il soit possible de lire directement les valeurs à partir du AttributeSet, cela 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 le AttributeSet à obtainStyledAttributes(). Cette méthode renvoie un TypedArray tableau de valeurs déjà déréférencées et stylisées.

Le compilateur de ressources Android effectue de nombreuses tâches pour faciliter l'appel de obtainStyledAttributes(). Pour chaque <declare-styleable> ressource du répertoire res/, le R.java généré définit à la fois un tableau d'ID d'attribut et un ensemble de constantes qui définissent l'index de chaque attribut du tableau. Vous utilisez les constantes prédéfinies pour lire les attributs à partir du TypedArray. Voici comment la PieChart classe 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 puissant 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 d'accesseurs et de mutateurs 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 que la vue se comporte de manière fiable. Vous devez invalider la vue après toute modification de ses propriétés susceptible de modifier son apparence, afin que le système sache qu'il doit être redessiné. De même, vous devez demander une nouvelle mise en page si une propriété change d'une manière susceptible d'affecter la taille ou la forme de la vue. Oublier ces appels de méthode peut entraîner des bugs difficiles à trouver.

Les vues personnalisées doivent également prendre en charge les écouteurs d'événements pour communiquer des événements importants. Par exemple, PieChart expose un événement personnalisé appelé OnCurrentItemChanged pour informer les écouteurs que l'utilisateur a fait pivoter le graphique à secteurs pour se concentrer sur une nouvelle part.

Il est facile d'oublier d'exposer des propriétés et des é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 orientée vers l'accessibilité

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

  • Libellez vos champs de saisie à l'aide de l'attribut android:contentDescription.
  • Envoyez des événements d'accessibilité en appelant sendAccessibilityEvent() quand approprié.
  • Prenez en charge d'autres manettes, telles qu'un pavé directionnel ou un trackball.

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