Android Kotlin

Cet article explique comment afficher la liste des versions Android via un RecyclerView, en Android avec le langage Kotlin.

Le RecyclerView est un composant visuel Android de type conteneur. Ce type de vue permet d’afficher un tableau d’éléments (ici le tableau des versions Android), sous forme de liste ou de grille. Il fonctionne avec un adaptateur ou adapter.

De manière générale, le concept d’adaptateur en Android permet de faire le lien entre la vue et les données.

L’implémentation se fait en trois étapes :

Implémentation liée aux données

Implémentation de l’adaptateur

Configuration de l’adaptateur avec sa vue

Implémentation liée aux données

Tout d’abord, il s’agit de mettre en place l’Activity principale.

Ensuite, il s’agit de créer une classe représentant nos éléments à afficher, plus précisément, une classe représentant une version d’Android. Pour commencer, notre version d’Android ne possède qu’un nom (name).

Puis, il s’agit de réaliser les implémentations liées aux données. En particulier, un tableau d’éléments va être déclaré dans l’Activity principale, ce dernier contient les données à afficher.

  1. Créez un nouveau projet Android Studio, dont l’Activity principale est MainActivity, avec le modèle EmptyActivity.

  2. Il s’agit de créer un nouveau fichier Kotlin contenant une data class, nommons la AndVersion :

     data class AndVersion(var name: String)
    

    Cette dernière permet de créer des objets de type AndVersion ayant un nom, “Lollipop”, par exemple val loli = AndVersion("Lollipop").

    Note : L’intérêt d’utiliser une classe de donnée est la génération automatique de fonction d’affichage tel que toString(), de copie d’objet, copy(), d’égalité, equals(), etc [1].

  3. Créez le tableau d’éléments dans la classe MainActivity :

     val andVersionArray = arrayOf(AndVersion("Banana"), AndVersion("Lollipop"))
    

Remarquez la valeur match_parent, pour les attributs android:layout_width et android:layout_height, cela signifie que la hauteur et la largeur doit correspondre au parent.

À présent, les données sont créées, présentes dans le tableau andVersionArray. Il s’agit, à présent, d’implémenter un adaptateur de données pour le composant visuel RecyclerView, soit une classe héritant de RecyclerView.Adapter.

Implémentation de l’adaptateur

Dans cette partie, il s’agit de créer un adaptateur pour une liste de versions Android. Plus précisément, nous allons créer une classe héritant de RecyclerView.Adapter.

  1. Déclarez une classe héritant de RecyclerView.Adapter

     class AndVersionAdapter(val items: Array<AndVersion>) : RecyclerView.Adapter<AndVersionAdapter.ViewHolder>() {
    
     }
    
  2. Ajoutez le fichier item_and_version.xml de la vue représentant une ligne, dans le dossier res/layout/ :

     <android.support.constraint.ConstraintLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:layout_height="@dimen/common_width">
    
         <TextView
             android:id="@+id/andVersionTxt"
             android:layout_width="@dimen/common_width"
             android:layout_height="@dimen/common_width" />
    
         <View
             android:layout_width="match_parent"
             android:layout_height="1dp"
             android:background="@color/colorPrimaryDark" />
     </android.support.constraint.ConstraintLayout>
    
  3. Ajoutez, dans la classe AndVersionAdapter, la composition (la inner class) :

     class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
             fun bindAndVersion(andVersion: AndVersion) {
                 with(andVersion) {
                     itemView.andVersionTxt.text = "$name"
                 }
             }
         }
    
  4. Ajoutez les méthodes d’héritage pour AndVersionAdapter :

    la fonction retournant le nombre d’éléments de la liste :

     override fun getItemCount(): Int = items.size
    

    la fonction retournant la visualisation d’une ligne de la liste :

     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
       val lineView = LayoutInflater.from(parent.context).inflate(R.layout.item_and_version, parent, false)
       return ViewHolder(lineView)
        }
    

    la fonction s’occupant de charger les données dans la vue :

     override fun onBindViewHolder(holder: ViewHolder, position: Int) {
             holder.bindAndVersion(items[position])
     }
    

À présent, l’implémentation de l’adaptateur est complète, il ne reste plus qu’à l’utiliser.

Configuration de l’adaptateur avec sa vue

À présent, il s’agit de déclarer dans la vue principale le RecyclerView, andVersionRecyclerView. Puis, il s’agira de configurer andVersionRecyclerView. En effet, il a besoin d’un gestionnaire d’agencement, LinearLayoutManager, ainsi que d’un adaptateur, AndVersionAdapter.

  1. Inclure la bibliothèque du RecyclerView dans le fichier build.gradle (Module: app) :

     implementation "com.android.support:recyclerview-v7:$support_version"
    
  2. Déclarez le composant RecyclerView dans la vue principale, activity_main.xml :

     <android.support.v7.widget.RecyclerView
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/andVersionRecyclerView"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
    
    
  3. Spécifiez un LinearLayoutManager pour l’objet andVersionRecyclerView, dans la méthode onCreate(), de l’Activity principale :

     andVersionRecyclerView.layoutManager = LinearLayoutManager(this)
    
  4. Spécifiez l’adaptateur pour l’objet andVersionRecyclerView, toujours dans la méthode onCreate(), de l’Activity principale :

     andVersionRecyclerView.adapter = AndVersionAdapter(andVersionArray)
    

    À présent, l’Activity principale MainActivity déclare un RecyclerView, andVersionRecyclerView. Ce dernier est configuré avec l’adaptateur AndVersionAdapter. Ici, vous devriez pouvoir exécuter le projet.

Plus loin

Avec cette première version, l’affichage de la vue via le ViewHolder n’est pas parfaitement optimale [5](cela est dû au côté obscur des extensions Kotlin). Afin d’y remédier, il faut, tout d’abord, autoriser les expérimentations avec les extensions Kotlin dans la partie android du fichier graddle (module) :

 androidExtensions {
        experimental = true
    }

Ensuite, il s’agit :

  • d’ajouter LayoutContainer comme une interface du ViewHolder, relatif à l’Adapter
  • d’initialiseer la constante containerView
    class ViewHolder(val view: View) : RecyclerView.ViewHolder(view), LayoutContainer {
          override val containerView: View?
              get() = itemView
    

    Enfin, il n’y a plus qu’à enlever les appels à itemView, soit :

    androidVersionName.text = name
    

    L’import de la vue import kotlinx.android.synthetic.main.item_android_version.view.* devient import kotlinx.android.synthetic.main.item_android_version.*.

En outre, il est possible d’utiliser une fonction d’extension pour charger la vue dans la méthode onCreateViewHolder() de la classe AndVersionAdapter :

fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View {
       return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
}

La méthode onCreateViewHolder() devient alors :

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AndVersionAdapter.ViewHolder {
    return ViewHolder(parent.inflate(R.layout.item_and_version))
}

Pour le moment seul le titre de la version s’affiche, il est possible d’ajouter une image.

Ajoutez l’élément graphique dans le fichier item_and_version.xml :

  <ImageView
      android:id="@+id/andVersionImg"
      android:layout_width="@dimen/common_width"
      android:layout_height="@dimen/common_width" />

Ajoutez l’attribut img dans la classe AndVersion :

data class AndVersion(var name: String, var img:Int)

Ajoutez les images dans le dossier res/drawable/.

Ajoutez le tableau de chaîne de caractères, dans strings.xml :

<string-array name="andVersionName">    
  <item>Cupcake</item>    
  <item>Donut</item>    
  <item>Eclair</item>
</string-array>

Ajoutez une fonction seedItems(), son rôle est d’initialiser les tableaux :

var nameArray = resources.getStringArray(R.array.andVersionName)
val imgArray = arrayOf(R.drawable.cupcake, R.drawable.donut, R.drawable.eclair)
for (i in 0..(nameArray.size-1))
            andVersionArray[i] = AndVersion(nameArray[i], imgArray[i])

Faites le lien entre la vue d’une ligne et la donnée dans le ViewHolder de l’adaptateur :

itemView.andVersionImg.setImageResource(img)

Il est aussi possible d’intercepter le clique sur l’image depuis le ViewHolder :

andVersionImg.setOnClickListener { itemView.context.toast("$name")}

Il est possible, dans certain cas, que les données de l’adaptateur change. À ce moment, la méthode notifyDataSetChanged() est utilisée sur l’objet de type adapter, ici andVersionRecyclerView.adapter.

Finalement, en trois quart d’heure top chrono il est possible d’implémenter un RecyclerView. Cela dit, c’est une implémentation qui demande à être pratiquée afin d’être parfaitement maîtrisée, selon les trois étapes d’implémentation :

Implémentation liée aux données

Implémentation de l’adaptateur

Configuration de l’adaptateur avec sa vue

L’intérêt d’utiliser un RecyclerView est de pouvoir, comme son nom l’indique, recycler les lignes à afficher. Ces dernières sont stockées en cache via le ViewHolder.

La complexité de ce développement réside dans l’appréhension du concept d’adaptateur. Ce concept est récurrent en Android, il s’applique avec des vues de type conteneur, comme le GridView, le ViewPager, le Spinner, etc. Chacune de ces vues possède son type d’adaptateur (RecyclerView.Adaptateur, FragmentStatePagerAdapter, SpinnerAdapter, etc.). L’adaptateur peut parfois être utilisé tel quel, sans être hérité comme on l’a fait dans cet article. Par exemple, avec le Spinner, il suffit d’indiquer un tableau de chaîne de caractère dans le constructeur de SpinnerAdapter.

En outre, la démonstration de cette liste de version Android est disponible dans la partie “Version Android” de l’application Kotlin pour Android sur Play Store.

Références

  1. Documentation Kotlin : Data classes
  2. Merge Request 6 Item List Adapter
  3. Merge Request 6 Shortcuts List Adapter
  4. Antonio Leiva: RecyclerView in Android: The basics
  5. Kotlin Android Extensions: Using View Binding the right way

Partagez ou réagissez sur Twitter.

Vous avez trouvé une erreur ou voulez améliorer cet article ? Editez le directement !

Comments