Utilisation d'un autre type de Views : ImageView

Objectifs de la partie

Enrichir notre compréhension de la notion de View (les composants graphiques) dans Android Studio par l'utilisation d'un autre type : les Image View et la réalisation d'un petit projet Android.

Les views, aussi appelées « widget » sur Android, sont n'importe quel composant graphique que l'on souhaite afficher dans son application. Dans le chapitre précédent, nous avons découvert les « SurfaceView » qui permettent juste de recevoir des primitives graphiques (droites, cercles, rectangles) et dont nous avons besoin pour nos deux animations graphiques.

Mais beaucoup d'autres views déjà « pré-dessinées » sont possibles comme les button, les text, etc.

Ici nous allons découvrir les « ImageView » dont l'idée est de faire apparaître des images à l'écran. Étant fan de Jazz, l'application que nous vous proposons de réaliser est la suivante.

Nous souhaitons faire apparaître une série de photos de musiciens de Jazz favoris à l'écran. Lorsque nous cliquons sur le bouton du bas, une autre photo apparaît. En cliquant à même l'image, l'image est modifiée : tant sa taille que la couleur en arrière-fond, comme vous pouvez le constater ici avec l'image d'origine à gauche et le résultat du click sur l'image à droite.

La première chose à faire est d'entreposer vos photos dans le répertoire « Drawables » de votre répertoire Ressources. C'est bien lui qui s'occupera de répertorier vos photos.

Découvrons maintenant le fichier activity_main.xml de notre application :

1
<?xml version="1.0" encoding="utf-8"?>
2
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:id="@+id/linearLayout"
4
    android:layout_width="match_parent"
5
    android:layout_height="match_parent"
6
    android:gravity="center"
7
    android:orientation="vertical">
8
9
    <ImageView
10
        android:id="@+id/imageView"
11
        android:layout_width="match_parent"
12
        android:layout_height="match_parent"
13
        android:scaleType="centerCrop"
14
        android:src="@drawable/brad" />
15
16
17
    <ImageButton
18
        android:id="@+id/imageButton"
19
        android:layout_width="wrap_content"
20
        android:src="@android:drawable/ic_menu_set_as"
21
        android:layout_gravity="bottom|center_horizontal"
22
        android:layout_height="wrap_content" />
23
24
25
</FrameLayout>

Nous voyons bien apparaître l'image et le bouton. ImageButton est une sous-classe d'ImageView qui a, en général, cette simple fonction, dictée par son apparence, de faire dérouler les images. On voit que le bouton est centré en bas.

Nous disposons ces 2 views dans une « FrameLayout », un autre des « Layout » de base d'Android, utilisé le plus souvent quand une seule et une seule view est censée occuper tout l'écran, ce qui est bien le cas ici. On peut voir dans la partie ImageView que la première image qui apparaît est celle de Brad Meldhau et que son format est « centerCrop ».

Voyons maintenant le code Kotlin qui va permettre d'animer cette application et de répondre tant au click sur le bouton du bas qu'à un click à même l'image.

1
package com.example.testimageview
2
3
import android.os.Bundle
4
import android.view.View
5
import android.widget.ImageButton
6
import android.widget.ImageView
7
import android.widget.Toast
8
import androidx.appcompat.app.AppCompatActivity
9
import androidx.core.content.ContextCompat
10
import kotlinx.android.synthetic.main.activity_main.*
11
12
class MainActivity : AppCompatActivity(), View.OnClickListener {
13
14
15
    val sampleDrawables = intArrayOf(R.drawable.brad, R.drawable.keith, R.drawable.john, R.drawable.pat)
16
17
    var i = 0
18
19
    val scaleType = arrayListOf(ImageView.ScaleType.CENTER_CROP, ImageView.ScaleType.FIT_CENTER, ImageView.ScaleType.CENTER_CROP, ImageView.ScaleType.FIT_XY)
20
21
    override fun onCreate(savedInstanceState: Bundle?) {
22
        super.onCreate(savedInstanceState)
23
        setContentView(R.layout.activity_main)
24
25
26
        imageView.setOnClickListener(this)
27
        imageButton.setOnClickListener(this)
28
    }
29
30
    override fun onClick(p0: View?) {
31
        when (p0) {
32
            is ImageButton -> if (i == sampleDrawables.size) {
33
                i = 0
34
                imageView.setImageResource(sampleDrawables[i])
35
                imageView.colorFilter = null
36
                i++
37
            } else {
38
                imageView.setImageResource(sampleDrawables[i])
39
                imageView.colorFilter = null
40
41
                i++
42
            }
43
            is ImageView -> {
44
                imageView.setColorFilter(ContextCompat.getColor(this, R.color.myColor))
45
                imageView.scaleType = scaleType.shuffled().take(1)[0]
46
            }
47
48
            else -> Toast.makeText(applicationContext, "Neither ImageView nor ImageButton", Toast.LENGTH_LONG).show()
49
        }
50
    }
51
}

Détaillons ce code quelque peu.

Comme attribut de la classe principale, nous trouvons 2 listes : la première renvoyant aux images stockées dans les ressources (il y en a 4 dans cet exemple) et la deuxième reprenant un ensemble de formats possibles d'image.

Dans la méthode onCreate, nous rendons les 2 boutons sensibles au click par le rajout du « setOnClickListener(this) », this, comme avant, renvoyant à l'interface dont hérite la classe principale et exigeant l'implémentation de la méthode onClick(View). Et justement que fait cette méthode ?

D'abord, elle repère où l'on clique : sur le bouton ou sur l'image. Si c'est sur le bouton, elle fait défiler l'image suivante et recommence au début quand on arrive à la dernière image. Si c'est directement sur l'image, elle la filtre par une couleur de fond qui a été rajoutée dans le fichier colors.xml de votre répertoire Ressources (dans le sous-répertoire values) et référé par « myColor », et modifie le formatage en tirant au hasard un des formats présents dans la liste déclarée au début de la classe.