Vous êtes sur la page 1sur 55

Chapitre 5 : Les Interfaces

graphiques avancées

Année Universitaire: 2022/2023 Audience : STIC-L2-SR


▪ Ce chapitre porte sur les interfaces utilisateur avancées, en montrant comment

créer des interfaces beaucoup plus riches, notamment :


▪ Comment intégrer des Widgets et listeners sur ces Widgets

▪ Comment créer une liste de contacts ou de pays ?

▪ Comment créer un menu ?

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 2
▪ Dans la littérature, les composants graphiques sont parfois nommés widget ou
contrôles.
▪ Le mot widget désigne l’ensemble des vues standards incluses dans la plate-forme
Android.
▪ Il est possible d’intégrer dans une interface plusieurs types de vues.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 3
▪ Exemple de Widgets:
▪ TextView : pour les labels texte;
▪ EditText : Champ de saisie;
▪ Button : bouton standard;
▪ ImageView : image

▪ RadioButton : radio (choix exclusif)


▪ CheckBox : case à cocher;
▪ ListView : Liste de vues horizontales;
▪ Spinner : Liste déroulante
▪ TimePicker : Choix de date
▪ ProgressBar : Bar de progression

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 4
▪ Les évènements permettent de gérer les actions utilisateurs sur les vues
▪ Pour gérer les évènements sur les vues, il suffit d’ajouter un écouteur:

edit.addTextChangedListener(new TextWatcher() { button.setOnClickListener(new


@Override View.OnClickListener()
public void onTextChanged(CharSequence s, int @Override
start, int before, int count) public void onClick(DialogInterface dialog, int
{ which)
// do something here { // Du code ici
} }
); });

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 5
Dans cet exemple on va intégrer les widgets suivants:
▪ une case à cocher (CheckBox),
▪ un bouton image (ImageButton),
▪ deux boutons radio (RadioGroup et RadioButton),
▪ un contrôle de saisie de date (DatePicker),
▪ une barre de vote (RatingBar) ,
▪ horloge digitale (DigitalClock)
▪ horloge analogique (AnalogClock).

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 6
RadioGroup et RadioButton

<!-- Groupe de boutons radio -->


<?xml version="1.0" encoding="utf-8"?> <RadioGroup
<LinearLayout android:id="@+id/RadioGroup01"
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_height="fill_parent"> android:orientation="horizontal"
android:layout_gravity="center_horizontal">
<!-- Case a cocher -->
<!-- Radio Bouton 1 -->
<CheckBox <RadioButton
CheckBox android:id="@+id/CheckBox01" android:id="@+id/RadioButton01"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Conditions acceptées ?"> android:text="Oui"
android:checked="true">
</CheckBox>
<!-- Nous avons mis checked=true par défaut sur notre 1er bouton
<!-- Bouton avec une Image --> radio afin qu’il soit coché -->
<ImageButton </RadioButton>
ImageButt android:id="@+id/ImageButton01" <!-- Bouton radio 2 -->
on android:layout_width="wrap_content" <RadioButton
android:layout_height="wrap_content" android:id="@+id/RadioButton02"
android:layout_width="wrap_content"
android:src="@drawable/icon">
android:layout_height="wrap_content"
<!-- @drawable/icon est une Image qui se trouve dans le dossier /res/ android:text="Non">
drawable de notre projet --> </RadioButton>
</ImageButton> </RadioGroup>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 7
DatePicker et RatingBar DigitalClock et AnalogClock

<!-- Sélectionneur de date --> <!-- Nous ajoutons un LinearLayout <!-- Horloge Digital -->
<DatePicker avec une orientation horizontale <DigitalClock
android:id="@+id/DatePicker01" afin d’afficher de gauche à droite les views android:text="Horloge"
android:layout_width="wrap_content" que nous allons grouper dedans --> android:id="@+id/DigitalClock01"
android:layout_height="wrap_content"> <LinearLayout android:layout_width="wrap_content"
</DatePicker> android:orientation="horizontal" android:layout_height="wrap_content"
<!-- Barre de vote --> android:layout_width="wrap_content" android:layout_gravity="center_vertical">
<RatingBar android:layout_height="wrap_content" </DigitalClock>
android:id="@+id/RatingBar01" android:layout_gravity="center_horizontal">
android:layout_width="wrap_content" <!-- Horloge Analogique -->
android:layout_height="wrap_content"> <AnalogClock
</RatingBar> android:id="@+id/AnalogClock01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</AnalogClock>
</LinearLayout>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 8
Main.java
import android.app.Activity; @Override
import android.os.Bundle; public void onCreate(Bundle savedInstanceState) {
import android.view.View; super.onCreate(savedInstanceState);
import android.view.View.OnClickListener; setContentView(R.layout.main);
import android.widget.CheckBox;
import android.widget.CompoundButton; ((CheckBox)findViewById(R.id.CheckBox01)).setOnCheckedChangeListener( new
import android.widget.DatePicker; CheckBox.OnCheckedChangeListener() {
import android.widget.ImageButton; public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) {
import android.widget.RadioButton;
import android.widget.RadioGroup; afficheToast("Case cochée ? : " + ((isChecked)?"Oui":"Non"));
import android.widget.RatingBar;
import android.widget.Toast; }
public class Main extends Activity { });

➢ Pour récupérer l’état de la case à cocher, il suffit de le récupérer avec la méthode isChecked.
➢ Dans notre exemple nous récupérons l’état dès qu’il change, grâce à l’écouteur OnCheckedChangeListener

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 9
Main.java
((DatePicker)findViewById(R.id.DatePicker01)).init(1977, 4, 29, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
afficheToast("La date a changé\nAnnée : " + year + " | Mois : " + monthOfYear + " | Jour : " +
dayOfMonth);
}
});

➢ L’horloge digitale (DigitalClock) : affiche une horloge digitale dans votre application. Par exemple : 10:05:25 ;
➢ L’horloge analogique (AnalogClock) : affiche une horloge à aiguilles dans votre application.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 10
RATINGBAR ET
Main.java
((RatingBar)findViewById(R.id.RatingBar01)).setOnRatingBarChangeListener( new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
afficheToast("Nouvelle note : " + rating);
}
});
((RadioGroup)findViewById(R.id.RadioGroup01)).setOnCheckedChangeListener( new
RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
afficheToast("Vous avez répondu : " + ((RadioButton)findViewById(checkedId)).getText());
} });

➢ La barre de vote (RatingBar) : affiche une barre comportant des étoiles pour représenter et/ou récupérer
une notation.
➢ Nous récupérons le changement de note dès que l’utilisateur modifie celle-ci grâce à l’écouteur
OnRatingBarChangeListener associé.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 11
➢ Afin que les boutons radio (de type RadioButton) puissent basculer de l’un à
l’autre, vous devez les regrouper dans un élément ViewGroup de type
RadioGroup.
➢ Si vos boutons radio ne sont pas regroupés dans un RadioGroup, ils seront tous
indépendants
➢ Le changement d’état des boutons radio dès qu’ils sont pressés grâce à l’écouteur
OnCheckedChangeListener que nous avons associé au RadioGroup.
➢ Si vous souhaitez récupérer le bouton radio pressé à n’importe quel moment il
vous suffira d’appeler la méthode getCheckedRadioButtonId.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 12
Main.java
IMAGEBUTTON)
((ImageButton)findViewById(R.id.ImageButton01)).setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
afficheToast("Bouton Image pressé");
}
});
}

public void afficheToast(String text) {


Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 13
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 14
▪ Les groupes sont des vues permettant de
▪ Définir un pattern d’affichage pour les collections d’objets comme:
▪ ListView
▪ Gridview
▪ Spinner
▪ Faire des choix sur un ensemble d’éléments comme RadioGroup

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 15
▪ La source de données est une liste d’objets pouvant provenir : d’une collection
statique, d’une base de données locale, d’un service web, etc.
▪ Les collections peuvent être:
▪ De type simple : String, Double, Integer, …
▪ De type complexe : Instance de classe java
▪ Les groupes utilisent des adapter pour insérer automatiquement les objets (Java)
comme item dans la liste.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 16
▪ Les adaptateurs servent à gérer les sources de données qui seront affichées dans
les différentes listes de l’interface utilisateur.
▪ Ils réalisent la liaison entre les sources de données (un simple tableau de chaînes
de caractères, une base de données, un fournisseur de contenu, etc.) et les
contrôles de l’interface utilisateur.
▪ Techniquement, un adaptateur est représenté par l’objet Adapter.
▪ Il permet de séparer vos données brutes sous diverses formes (array, cursor,
bitmap, etc.) en éléments visuels manipulables (navigation, sélection, clic).
Source de Adapter
Adapter
données View
• ArrayList • ListView
• Cursor • GridView
• Spinner
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 17
▪ Puisque Adapter est une interface, il n’existe pas d’objet Adapter utilisable en
l’état.
▪ Il existe plusieurs types d’adaptateurs pour différents type de données permettant
de traiter les types les plus courants :
▪ ArrayAdapter<T> : pour tous les types de tableaux ;
▪ CursorAdapter : pour traiter les données de type Cursor qui se lie directement à
un jeu de résultats à partir d'une base de données SQLite locale;
▪ BaseAdapter : pour créer des adaptateurs personnalisés ;

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 18
▪ Une ListView est une vue de groupe qui peut afficher des éléments sous forme d’une liste
déroulante horizontale
▪ Si vous avez une longue liste, un ListView défile automatiquement, sans code
supplémentaire nécessaire.
▪ Pour afficher une liste d’éléments cliquables, nous avons besoin de trois choses :
▪ des données : Array, ArrayList, Cursor... ;
▪ un Adapter qui fera l’interface entre données et les vues ;
▪ une ListView qui fera l’interface entre l’adaptateur et l’utilisateur.

Utilisateur
Gestion des cliques
Affichage ListView
Gestion des vues
Adapter ArrayAdapter
Gestion des ressources
Données Array
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 19
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp" />
</LinearLayout>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 20
ListView lst = findViewById(R.id.listView1);
String[] tableau = new String[]{ "Algorithms", "Data Structures","Languages", "Web Technologies"};
ArrayAdapter<String> adapter = new ArrayAdapter <String> ( this, android.R.layout.simple_list_item_1, tableau);
lst.setAdapter(adapter);

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 21
▪ Au sein d'un layout, on peut implanter une liste que l'on pourra dérouler si le
nombre d'éléments est important.
▪ Si l'on souhaite faire une liste plein écran, il suffit juste de poser un layout linéaire
et d’y insérer une ListView.
▪ Etant donné qu'une liste peut contenir des éléments graphiques divers et variés,
les éléments de la liste doivent être insérés dans un ListAdapter et il faut aussi
définir le layout qui sera utilisé pour afficher chaque élément du ListAdapter.
▪ Prenons un exemple simple: une liste de chaine de caractères. Dans ce cas, on créé
un nouveau layout et on ajoute dynamiquement un ArrayAdapter à la liste listView.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 22
▪ Lorsque les listes contiennent un layout plus complexe qu'un texte, il faut utiliser un
autre constructeur de ArrayAdapter où resource est l'id du layout à appliquer à chaque
ligne et textViewResourceId est l'id de la zone de texte inclu dans ce layout complexe.
▪ A chaque entrée de la liste, la vue générée utilisera le layout complexe et la zone de
texte contiendra la string passée en argument à la méthode add.
ArrayAdapter (Context context, int resource, int textViewResourceId)
ListView list = (ListView)findViewById(R.id.maliste);
ArrayAdapter<String> tableau = new ArrayAdapter<String>( this, R.layout.ligne, R.id.monTexte);
for (int i=0; i<40; i++) {
tableau.add("coucou " + i); }
list.setAdapter(tableau);

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
▪ Avec le layout de liste suivant (ligne.xml): xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

Interface résultat : <LinearLayout


android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/monTexte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />

<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="@android:drawable/ic_input_add" />

</LinearLayout> </LinearLayout>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques 2022/2023 24


avancées
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 25
▪ Un spinner fournit un moyen rapide de sélectionner une valeur dans un ensemble.
▪ En touchant le spinner, il affiche une liste déroulante avec toutes les valeurs
disponibles, à partir de laquelle l'utilisateur peut en sélectionner une.
▪ Si vous avez une longue liste de choix, un spinner défile automatiquement, sans
code supplémentaire nécessaire.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 26
➢ Pour créer un spinner dans votre mise en page XML, ajoutez un élément Spinner, qui fournit la
liste déroulante :

<Spinner
android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Spinner>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 27
▪ L’adaptateur va remplir la liste de spinner avec des valeurs.
▪ Il prend l'ensemble de données que vous avez spécifié et crée une vue pour chaque
élément de l'ensemble de données.
▪ Les valeurs que vous fournissez pour le spinner peuvent provenir de n'importe quelle
source, mais doivent être fournies via un SpinnerAdapter, tel qu'un ArrayAdapter si les
valeurs sont disponibles dans un tableau.
▪ Vous pouvez utiliser un CursorAdapter si les valeurs peuvent provenir d'une source telle
qu'un fichier stocké ou une base de données.

Array ArrayAdapter Spinner

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 28
▪ L'exemple suivant montre un tableau simple appelé labels_array de valeurs
prédéterminées dans le fichier strings.xml :

<string-array name="labels_array">
<item>Home</item>
<item>Work</item>
<item>Mobile</item>
<item>Other</item>
</string-array>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 29
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Spinner spinner = (Spinner) findViewById(R.id.label_spinner);


if (spinner != null) {
spinner.setOnItemSelectedListener(this);
}
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.labels_array,
android.R.layout.simple_spinner_item);

adapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item);
if (spinner != null) {
spinner.setAdapter(adapter);
}
}
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 30
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {

}
public void onItemSelected (AdapterView<?> adapterView, View view, int pos, long id) {
String spinner_item = adapterView.getItemAtPosition(pos).toString();
//
}
public onNothingSelected(AdapterView<?> adapterView)[
//
}

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 31
▪ Spinner vous permet de sélectionner un élément dans un menu déroulant.
▪ Exemple :

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 32
SPINNER
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout>

Spinner sp = (Spinner)findViewById(R.id.spinner1);
String[] tableau = new String[]{ "Algorithms", "Data Structures","Languages", "Web Technologies"};
ArrayAdapter<String> dataAdapter = new ArrayAdapter <String> (this, android.R.layout.simple_spinner_item, tableau);

dataAdapter.setDropDownViewResource ( android.R.layout.simple_spinner_dropdown_item);

sp.setAdapter(dataAdapter );

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 33
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 34
▪ Une GridView est une vue de groupe disposant des éléments déroulantes de
manière bidimensionnel dans une interface
▪ Une GridView utilise des adapters pour remplir son contenu en fonction de la
collection d’objets qui lui est fournie.
▪ Exemple :

Grid de 3 colonnes Grid de 2 colonnes

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 35
▪ Une GridView peut être utilisée comme racine d’une interface

<?xml version="1.0" encoding="utf-8"?>


<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 36
▪ Peut être utilisée comme sous vue d’un layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/id_accueil"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</RelativeLayout>
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 37
GridView grd = (GridView) findViewById(R.id.gridview);

String[] tableau = new String[]{ "Algorithms", "Data Structures","Languages", "Web Technologies"};

ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, tableau);

grd.setAdapter(dataAdapter );

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 38
• Les groupes permettent la gestion d’évènement sur les éléments qu’ils contiennent.

gridview.setOnItemClickListener(new lst.setOnItemClickListener(new
AdapterView.OnItemClickListener() { AdapterView.OnItemClickListener() {

@Override @Override
Public void onItemClick(AdapterView<?> parent, View v, int public void onItemClick(AdapterView<?> parent, View view, int
position, long id) { position, long id) {
// Ce qui se passe quand on clique sur un élément } Toast.makeText(getApplicationContext(),"Click ListItem
}); Number " + (String) parent.getItemAtPosition(position),
Toast.LENGTH_LONG).show();
gridview.setOnLongClickListener(new OnLongClickListener() { }
@Override });
public boolean onLongClick(View v) {
//Ce qui se passe quand on reste appuyé sur un élément
}
});

• De même, pour le spinner, mettez à jour l'activité qui utilise le spinner pour implémenter
l'interface AdapterView.OnItemSelectedListener.
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 39
▪ Grâce au SimpleCursorAdapter, Android dispose d’un outil puissant pour gérer de façon
simple et efficace des données complexes pour afficher par exemple une liste de contacts,
un journal d’appels ou tout autre type de données issues d’une base de données.
▪ Exemple, exécuter une requête pour récupérer la liste des numéros dans le journal des
appel. D’abord, un objet Adapter est créé. Puis, il sera associé à un contrôle ListView.
public Cursor cursor = managedQuery(Calls.CONTENT_URI, null, null, null, null);
SimpleCursorAdapter( SimpleCursorAdapter adapter = new SimpleCursorAdapter( this,
android.content.Context context android.R.layout.simple_list_item_2, cursor, L’identifiant de fichier XML
, int layout new String[]{ comportant les éléments à
, android.database.Cursor c Calls.NUMBER, Données sur les numéros afficher.
, java.lang.String[] from Calls.CACHED_NAME} , Données sur les noms
, int[] to); new int[]{ des contacts
android.R.id.text1, Afficher les numéros
android.R.id.text2}); Afficher les noms des contacts
list.setListAdapter(adapter);
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 40
▪ La flexibilité et la modularité du modèle objet des adaptateurs permet de
bénéficier de la puissance de ceux existants pour former la base d’un nouvel
adaptateur.
▪ Il est possible de créer un adaptateur personnalisé.
▪ Il est important de pouvoir bénéficier des méthodes de base de l’objet
BaseAdapter.
▪ Exemple : créer un adaptateur personnalisé permettant de gérer des chaînes de
caractères.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 41
➢ Il faut avant tout réfléchir en amont au type des données qu’il traite
➢ et si possible, utiliser un adaptateur déjà existant.

public class MyCustomAdapter extends BaseAdapter{


LayoutInflater inflater;
String[] data; ➢ Le constructeur se composera
... de deux paramètres essentiels
MyCustomAdapter(Context context, String[] data) : le contexte et les données.
{
this.data = data;
this.inflater = LayoutInflater.from(context);
}

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 42
public class MyCustomAdapter extends BaseAdapter{ ➢ L’implémentation des méthodes qui permettent la
récupération des données, getCount, getItem et

getItemId constitue une étape importante.
@Override ➢ getCount : renvoie le nombre d’éléments
contenus dans la collection de données
public int getCount() {return data.length; } ➢ getItem : permet d’accéder aux données en
indiquant une position absolue dans la
@Override
collection.
public Object getItem(int position) {return data[position];} ➢ getItemId : permet de séparer l’ordre naturel
des données de leur position dans la liste. Cela
@Override permet de réaliser des tris sur les données par
la suite
public long getItemId(int position) {return position; }
@Override ➢ getView : Permet de relier les données aux vues qui
afficheront celles-ci.
public View getView( int position , View convertView , ViewGroup parent) {
convertView = inflater.inflate( android.R.layout.simple_list_item_1, null); ➢ L’objet LayoutInflater permet de charger le fichier
XML grâce à la méthode inflate.
TextView t1 = (TextView) convertView.findViewById( android.R.id.text1);
➢ Puis nous retrouvons une instance d’un TextView
t1.setText ( data[position] ); avec findViewById.
return convertView; ➢ Puis nous associons la donnée adéquate à son
contenu en définissant sa propriété Text.
}}
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 43
➢ void add(T object) : Ajouter un objet à un adaptateur
➢ void insert (T object, int position) : Insérer un objet à une position particulière
➢ T getItem (int position) : récupérer un objet dont on connaît la position
➢ int getPosition (T object) : récupérer la position d’un objet précis
➢ void remove (T object) : supprimer un objet
➢ void clear() : vider complètement l’adaptateur

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 44
➢ La barre d'application (également appelée barre d'action) est un espace dédié en
haut de chaque écran d'activité. Lorsque vous créez une activité à partir d'un
modèle (tel qu’un Empty Activity), une barre d'application est automatiquement
incluse pour l'activité.
➢ Si vous ajoutez un menu d'options, vous devez utiliser la barre d'outils Toolbar de la
bibliothèque de support d'appcompat v7 comme barre d'application.
➢ La barre d'application affiche par défaut le titre de l'application ou le nom défini
dans AndroidManifest.xml par l'attribut android:label pour l'activité.
➢ Lorsque votre activité démarre, le système remplit les éléments d'action en
appelant la méthode onCreateOptionsMenu() de votre activité (qu’on va voir par la
suite). Cette méthode permet d’afficher (inflate) une ressource de menu qui définit
tous les éléments d'action.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 46
▪ Chaque menu est lié à une activité, c’est pourquoi toutes les opérations que nous
allons traiter dans cette partie se réfèrent à une activité. Pour proposer plusieurs
menus vous aurez donc besoin de le faire dans chaque activité de votre
application.
▪ Le menu permet de naviguer vers d'autres activités de l'application ou vers les
principales options qui affectent l'utilisation de l'application elle-même.
▪ Par exemple, votre menu d'options peut proposer à l'utilisateur des choix pour
naviguer vers d'autres activités, telles que passer une commande, ou pour des
actions qui ont un impact global sur l'application, telles que la modification des
paramètres ou des informations de profil.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 47
▪ Pour créer un menu, il vous suffit de surcharger la méthode onCreateOptionsMenu
de la classe Activity.
▪ Cette méthode est appelée la première fois que l’utilisateur appuie sur le bouton
menu de son téléphone.
▪ Elle reçoit en paramètre un objet de type Menu dans lequel nous ajouterons nos
éléments ultérieurement.
▪ Si l’utilisateur appuie une seconde fois sur le bouton Menu, cette méthode ne sera
plus appelée tant que l’activité ne sera pas détruite puis recréée.
▪ Si vous avez besoin d’ajouter, de supprimer ou de modifier un élément du menu
après coup, il faudra surcharger une autre méthode, la méthode
onPrepareOptionsMenu.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 48
Créez une nouvelle classe d’activité, dans laquelle vous placerez le contenu suivant :
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class Main extends Activity { ➢ Dans cette méthode, nous créons deux
éléments de menu Paramètres et Quitter.
private final static int MENU_PARAMETRE = 1;
private final static int MENU_QUITTER = 2;
➢ Il faut choisir un identifiant pour les items.
@Override L’ordre indique la priorité de cet item ; mettre
public void onCreate(Bundle savedInstanceState) { Menu.NONE s’il n’y en a pas.
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
➢ On peut mettre une icone avec setIcon() à la
}
place d’un texte
@Override ➢ menu.add(0, MENU_PARAMETRE,
public boolean onCreateOptionsMenu(Menu menu) { Menu.NONE, "Paramètres").setIcon
menu.add(0, MENU_PARAMETRE, Menu.NONE, "Paramètres"); (R.drawable.icon);
menu.add(0, MENU_QUITTER, Menu.NONE, "Quitter");
return true;
}
Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 49
Voici la seconde méthode, c’est un aiguillage selon l’item choisi :
@Override ➢ La méthode
public boolean onOptionsItemSelected(MenuItem item) { onOptionsItemSelected est
switch (item.getItemId()) { appelée lorsque l’utilisateur
clique sur l’un des éléments
case MENU_PARAMETRE: du menu.
Toast.makeText(this, "Ouverture des paramètres", Toast.LENGTH_SHORT).show(); ➢ Dans notre cas, si
return true; l’utilisateur clique sur
l’élément Paramètres
case MENU_QUITTER: l’application affiche un
finish(); message, alors qu’un clic
return true; sur Quitter ferme l’activité
grâce à la méthode finish.
default:
return true;
} } }

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 50
➢ Pour créer un menu, commencez par créer un fichier de définition d’interface qui se trouve sous
res/menu/menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/favorite"
android:icon="@drawable/ic_menu_favorite"
android:title="@string/favorite" <item
android:contentDescription="content_description_favorite" android:id="@+id/favorite"
app:showAsAction="ifRoom" /> android:icon="@drawable/ic_menu_favorite"
android:title="@string/favorite"
<item
android:contentDescription="@string/content_descripti
android:id="@+id/search"
android:title="@string/search" on_favorite"
android:contentDescription="content_description_search" app:showAsAction="ifRoom" />
app:showAsAction="ifRoom" />
➢ android:showAsAction=["ifRoom" | "never" |
<item "withText" | "always" | "collapseActionView"]
android:id="@+id/more" ➢ Cet attribut modifie la visibilité de l’item du
android:title="@string/more"
menu dans la barre d’action.
android:contentDescription="content_description_more"
app:showAsAction="never" />
</menu> 2022/2023 51
➢ Il faut programmer deux méthodes : L’une affiche le menu, l’autre réagit quand l’utilisateur
sélectionne un item.

@Override ➢ La méthode onCreateOptionsMenu sera


public boolean onCreateOptionsMenu(Menu menu) appelée uniquement la première fois lorsque
{ l’utilisateur appuiera sur le bouton Menu.
// ajouter mes items de menu
getMenuInflater().inflate(R.menu.nom_du_menu, menu); ➢ Cette méthode rajoute les items du menu
// ajouter les items du système s'il y en a défini dans le XML.
return super.onCreateOptionsMenu(menu); ➢ Un MenuInflater est un lecteur/traducteur de
} fichier XML en vues ; sa méthode inflate crée
les vues.

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 52
Voici la seconde méthode, c’est un aiguillage selon On peut la transformer en conditionnelles en
l’item choisi : cascade :

@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { int id = item.getItemId();
case R.id.menu_creer: if (id == R.id.menu_creer) {
... ...
return true; return true;
case MENU_ITEM1: } else if (id == MENU_ITEM1) {
... ...
return true; return true;
... ...
default: return super.onOptionsItemSelected(item); }
} else return super.onOptionsItemSelected(item);
} }

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 53
@Override
public boolean onOptionsItemSelected ( MenuItem item) {
int id = item.getItemId();
if (id == R.id.option_1){
Toast.makeText(this, "Ouverture des option1", Toast.LENGTH_SHORT).show();
return true;}
else if (id== R.id.option_2){
Toast.makeText(this, "Ouverture des option2", Toast.LENGTH_SHORT).show();
return true;}
else if (id== R.id.option_3){
Toast.makeText(this, "Ouverture des option3", Toast.LENGTH_SHORT).show();
return true;}
else
return super.onOptionsItemSelected(item);
}

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 54
Définir deux niveaux quand la barre d’action est trop petite :
<menu xmlns:android="..." >
<item android:id="@+id/menu_item1" ... />
<item android:id="@+id/menu_item2" ... />
<item android:id="@+id/menu_more"
android:icon="@drawable/ic_action_overflow"
android:showAsAction="always"
android:title="@string/menu_more">
<menu>
<item android:id="@+id/menu_item3" ... />
<item android:id="@+id/menu_item4" ... />
</menu>
</item>
</menu>

Programmation des applications mobiles - Chapitre 5 : Les interfaces graphiques avancées 2022/2023 55

Vous aimerez peut-être aussi