• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 04/05/2018

Créez votre première vue personnalisée

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre, nous allons créer notre première vue personnalisée et implémenter ainsi un TextView que nous personnaliserons pour les besoins de notre application. 

D'ailleurs, notre besoin est assez simple : nous aimerions pouvoir changer la police de nos TextView depuis le layout de nos contrôleurs. En fait, je l'avoue, cela représente surtout une parfaite excuse pour vous montrer comment créer une vue personnalisée ! :lol:

Je vous laisse ainsi créer une classe que vous appellerez  WonderTextView.java  et que vous placerez dans le package  views/  de votre application.

Classe views/WonderTextView.java :

public class WonderTextView extends AppCompatTextView {

    public WonderTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WonderTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}

Explications : Et voilà, nous avons créé une classe  WonderTextView héritant de  AppCompatTextView. Nous récupèrerons donc automatiquement toutes les propriétés et comportements d'un TextView, chouette ! :)

Maintenant nous allons nous rendre sur le site Font de Google et télécharger le fichier zip contenant les différentes variations de la police Roboto, très appréciée dans le monde du Material Design... ;) 

Aperçu de la police
Aperçu de la police "Roboto"

Une fois le fichier zip ouvert, créez un dossier  assets/  dans le répertoire  app/src/main de votre application. Puis, ajoutez-y un dossier que vous appellerez fonts/ et placez-y les fichiers suivants : Roboto-Bold.ttf, Roboto-Light.ttfRoboto-Medium.ttf et Roboto-Thin.ttf.

Résultat
Résultat

Et voilà ! Ces fichiers représentent 4 variations (gras, léger, moyen et fin) de la police Roboto, ce qui nous suffira largement dans notre cas. L'objectif maintenant est de récupérer ces fichiers, via leur nom, depuis notre classe  WonderTextView ... :-°

Pour nous aider dans cette périlleuse tâche, nous allons créer le fichier attrs.xml que nous placerons dans le dossier  res/values

Fichier attrs.xml :

<resources>
    <declare-styleable name="WonderTextView">
        <attr name="fontName" format="enum">
            <enum name="Roboto_Bold" value="1" />
            <enum name="Roboto_Light" value="2" />
            <enum name="Roboto_Medium" value="3" />
            <enum name="Roboto_Thin" value="4" />
        </attr>
    </declare-styleable>
</resources>

Explications : Vous ne connaissez probablement pas ce fichier, mais celui-ci est utilisé principalement pour définir des propriétés XML sur des vues personnalisées. Ainsi dans notre cas, il nous permettra d'ajouter la propriété  fontName  à notre vue  WonderTextView directement depuis les layouts de nos écrans. Cela nous servira par la suite à y placer le nom de la police souhaitée !

Cas d'utilisation
Exemple de cas d'utilisation

Nous allons également ajouter le nom des différentes variations de la police Roboto que nous utiliserons à l'intérieur de notre fichier  strings.xml  afin d'y avoir accès plus facilement.

Aperçu du fichier strings.xml :

<resources>
    ...

    <!-- FONT ID -->
    <string name="Roboto_Bold">Roboto-Bold</string>
    <string name="Roboto_Medium">Roboto-Medium</string>
    <string name="Roboto_Light">Roboto-Light</string>
    <string name="Roboto_Thin">Roboto-Thin</string>
    
</resources>

Explications : Nous répertorions simplement les différents noms des fichiers représentant les variations de la police Roboto.

Pour terminer, modifions notre classe  WonderTextView  afin de pouvoir gérer cette police quand l'utilisateur la spécifie via l'attribut XML  fontName ... :)

Fichier WonderTextView.java :

public class WonderTextView extends AppCompatTextView {

    public WonderTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.applyStyle(context, attrs);
    }

    public WonderTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.applyStyle(context, attrs);
    }

    // ---

    private void applyStyle(Context context, AttributeSet attrs){
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WonderTextView);
        int cf = a.getInteger(R.styleable.WonderTextView_fontName, 0);
        int fontName;
        switch (cf) {
            case 1:
                fontName = R.string.Roboto_Bold;
                break;
            case 2:
                fontName = R.string.Roboto_Light;
                break;
            case 3:
                fontName = R.string.Roboto_Medium;
                break;
            case 4:
                fontName = R.string.Roboto_Thin;
                break;
            default:
                fontName = R.string.Roboto_Medium;
                break;
        }

        String customFont = getResources().getString(fontName);

        Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/" + customFont + ".ttf");
        setTypeface(tf);
        a.recycle();
    }
}

Explications : Nous avons créé la méthode  applyStyle()  que nous appelons à travers les deux constructeurs de notre classe  WonderTextView. Celle-ci sera responsable de la récupération de l'ensemble des attributs de notre vue ainsi que leur valeur, et notamment celle de l'attribut  fontName. Une fois la valeur récupérée, nous récupérerons la police correspondante depuis le dossier fonts/de notre application et l'appliquerons à notre TextView.

Et c'est tout ! Changez maintenant l'ensemble des TextView utilisés dans le layout  fragment_detail.xml  par notre vue personnalisée  WonderTextView  comme ceci :

Extrait de fragment_detail.xml :

<LinearLayout 
    ... >

    <LinearLayout
        ... >

        ...

        <LinearLayout
            ... >

            <com.openclassrooms.wonder.views.WonderTextView
                android:id="@+id/fragment_detail_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginRight="56dip"
                style="@style/WonderText.Title"
                app:fontName="Roboto_Medium"/>

            <com.openclassrooms.wonder.views.WonderTextView
                android:id="@+id/fragment_detail_description"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:maxLines="3"
                android:layout_weight="1"
                android:ellipsize="end"
                app:fontName="Roboto_Light"/>

            <com.openclassrooms.wonder.views.WonderTextView
                android:id="@+id/fragment_detail_views"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                app:fontName="Roboto_Light"/>

            <com.openclassrooms.wonder.views.WonderTextView
                android:id="@+id/fragment_detail_likes"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                app:fontName="Roboto_Light"/>

            <com.openclassrooms.wonder.views.WonderTextView
                android:id="@+id/fragment_detail_comments"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                app:fontName="Roboto_Light"/>

            ...

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

Explications : Nous avons appelé directement dans ce layout notre classe  WonderTextView  dans le but de remplacer tous les précédents TextView. Nous avons également configuré pour chacun l'attribut  app:fontName  afin de définir une police particulière... :)

Lancez maintenant votre application et admirez le résultat à travers l'écran de détail.

Aperçu du résultat
Aperçu du résultat

Et voilà ! Vous venez de créer votre première vue personnalisée affichant du texte en police Roboto. Bravo ! N'hésitez pas à reproduire cette expérience avec d'autres classes comme Button par exemple... ;) Le champ des possibles est infini !

Exemple de certificat de réussite
Exemple de certificat de réussite