TP 4 : Gestion d'une
liste de films
2LM
Objectif pédagogique
Développez une application Android permettant de gérer une liste de films avec les fonctionnalités suivantes :
Fonctionnalités principales :
1. Affichage de films
o Affichez une liste de films (nom et année) à l’aide d’un RecyclerView.
o Les données sont stockées dans une ArrayList.
2. Utilisation de ViewBinding
o Utilisez ViewBinding pour accéder aux vues de manière sécurisée et moderne.
3. Menu dans la barre d'action Ajoutez un menu dans la barre d'action contenant les options suivantes :
o About Us
Affiche un Toast contenant le message "isitcom".
Cette option doit apparaître directement dans la barre d’action avec une icône d'information.
o Visiter IMDB
Ouvre le site IMDB dans le navigateur.
Cette option doit apparaître dans le menu déroulant (trois points) avec une icône de navigateur.
o Appeler
Ouvre l'application téléphone avec le numéro "+216 12345678" pré-rempli.
Cette option doit également apparaître dans le menu déroulant (trois points) avec une icône de
téléphone.
4. Menu contextuel sur les éléments de la liste
o Lors d’un appui long sur un film dans le RecyclerView, un menu contextuel s’affiche avec deux
options :
▪ Modifier
Ouvre une boîte de dialogue personnalisée permettant de modifier le nom du film.
Cette boîte de dialogue doit être stylisée et contenir deux boutons :
▪ Confirmer : applique la modification
▪ Annuler : ferme la boîte de dialogue sans changement
▪ Supprimer
Affiche une AlertDialog pour confirmer la suppression du film sélectionné.
En cas de confirmation, le film est supprimé de la liste.
Figure 1 : Vue générale MainActivity
Figure 2 : menu contextuel avec deux options : Editer et Supprimer,
si l'utilisateur faire une longue presse sur un item du RecycleView
Figure 4 : modifier le nom du film Figure 3 : Confirmation de la
avec le Dialogue personnalisé suppression avec AlertDialog
Figure 5 : Structure du projet
🛠️ Étapes de réalisation
Partie 1 : Création du projet
• Créer un nouveau projet Android avec une activité vide.
• Activer ViewBinding dans le fichier [Link] (Module: app):
android {
……………………..
…………………….
buildFeatures {
viewBinding = true
}
}
Then click "Sync Now" in Android Studio.
Partie 2 : Définition du modèle de données
• Créer une classe Film avec les attributs nom (String) et annee (int).
public class Film {
private String nom;
private int annee;
/* complete the code */ //////////// constructors
/* complete the code */ //////////// getters and setters
Partie 3 : Création du layout pour les éléments de la liste
• Créer un fichier item_film.xml dans le dossier res/layout avec deux TextView pour afficher le nom et
l'année du film.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvNom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#D78223" /> <!-- Bleu foncé -->
<TextView
android:id="@+id/tvAnnee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#B27777" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="#2196F3" />
</LinearLayout>
Partie 4.1 : Modifier le thème(light and dark) de l’application pour afficher le bar d’action
Dans res/values/themes/[Link]
effacer .NoActionBar
<resources xmlns:tools="[Link]
<!-- Base application theme. -->
<style name="[Link]" parent="[Link]">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="[Link]" parent="[Link]" />
</resources>
Partie 4.2 : Creé un dossier ‘menu’ dans res
Crée un fichier main_menu.xml (res/menu/main_menu.xml)
<menu xmlns:app="[Link]
xmlns:android="[Link]
<item android:id="@+id/about"
android:title="About Us" />
<item android:id="@+id/imdb"
android:title="Visiter IMDB"
app:showAsAction="never" />
<item android:id="@+id/call"
android:title="Appeler"
app:showAsAction="never" />
</menu>
Partie 4.3 : Dans res/menu/ menu_contextuel.xml:
Crée un fichier menu_contextuel.xml (res/menu/main_menu.xml)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="[Link]
<item
android:id="@+id/action_edit"
android:title="Edit" />
<item
android:id="@+id/action_delete"
android:title="Delete" />
</menu>
Partie 5 : Dialogue perso (res/layout/dialog_edit_movie.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp"
>
<TextView
android:id="@+id/dialogTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Modifier le film"
android:textSize="20sp"
android:textStyle="bold"
android:layout_gravity="center"
android:textColor="#000000"
android:paddingBottom="10dp" />
<EditText
android:id="@+id/editTextMovieName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nom du film"
android:padding="12dp"
android:textColor="#000000"
android:textColorHint="#888888"
android:layout_marginBottom="20dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end">
<Button
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Annuler"
android:backgroundTint="#B0BEC5"
/>
<Button
android:id="@+id/btnConfirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Confirmer"
android:backgroundTint="#4CAF50"
/>
</LinearLayout>
</LinearLayout>
Partie 6 : Ajoutez le layout activity_main.xml
Avec un RecyclerView avec l'id recyclerView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="[Link]
xmlns:app="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<[Link]
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" />
</LinearLayout>
Partie 7 : Adapter du RecyclerView
Créez un fichier [Link] :
package [Link];
/* complet the code */ // imports
public class FilmAdapter extends
[Link]<[Link]> {
private List<Film> filmList;
private OnItemLongClickListener listener;
public interface OnItemLongClickListener {
void onItemLongClick(View view, int position);
}
public void setOnItemLongClickListener(OnItemLongClickListener l) {
listener = l;
}
public FilmAdapter(List<Film> filmList) {
[Link] = filmList;
}
public class FilmViewHolder extends [Link] implements
[Link] {
TextView nom, annee;
public FilmViewHolder(View itemView) {
super(itemView);
nom = [Link]([Link]);
annee = [Link]([Link]);
[Link](this);
[Link](v -> {
if (listener != null)
[Link](v, getAdapterPosition());
return false;
});
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
[Link] menuInfo) {
[Link]("Options");
[Link](getAdapterPosition(), [Link].action_edit, 0, "Éditer");
[Link](getAdapterPosition(), [Link].action_delete, 1, "Supprimer");
}
}
@Override
public FilmViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =
[Link]([Link]()).inflate([Link].item_film, parent,
false);
return new FilmViewHolder(view);
}
@Override
public void onBindViewHolder(FilmViewHolder holder, int position) {
Film f = [Link](position);
[Link]([Link]);
[Link]([Link]([Link]));
}
@Override
public int getItemCount() {
return [Link]();
}
}
Partie 8 : MainActivity avec ViewBinding
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private List<Film> filmList = new ArrayList<>();
private FilmAdapter adapter;
private int selectedPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
binding = [Link](getLayoutInflater());
setContentView([Link]());
// Initialisation des films
[Link](new Film("Interstellar", 2014));
[Link](new Film("Inception", 2010));
[Link](new Film("The Matrix", 1999));
// Configuration du RecyclerView
adapter = new FilmAdapter(filmList);
[Link](new LinearLayoutManager(this));
[Link](adapter);
// Gestion du clic long pour enregistrer la position sélectionnée
[Link]((view, position) -> {
selectedPosition = position;
[Link](); // Pour afficher le menu
contextuel
});
registerForContextMenu([Link]);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
/* complete the code */ // actions when an item is selected
return [Link](item);
}
private void showDeleteConfirmation() {
new [Link](this)
.setTitle("Confirmation")
.setMessage("Voulez-vous vraiment supprimer ce film ?")
.setPositiveButton("Oui", (d, which) -> {
/* complete the code */ // supprimer le film
[Link](selectedPosition);
})
.setNegativeButton("Non", null)
.show();
}
private void showEditDialog() {
Dialog dialog = new Dialog(this);
[Link]([Link].dialog_edit_movie);
EditText editText = [Link]([Link]);
Button btnConfirm = [Link]([Link]);
Button btnCancel = [Link]([Link]);
// Préremplir le champ avec le nom actuel
[Link]([Link](selectedPosition).getNom());
[Link](v -> {
String newName = [Link]().toString().trim();
if (![Link]()) {
[Link](selectedPosition).setNom(newName);
[Link](selectedPosition);
[Link](this, "Nom modifié", Toast.LENGTH_SHORT).show();
[Link]();
} else {
[Link](this, "Veuillez entrer un nom",
Toast.LENGTH_SHORT).show();
}
});
[Link](v -> {
/* complete the code */ // Ferme le dialog sans rien faire
});
[Link]();
}
// Menu de l'action bar
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate([Link].main_menu, menu);
return true;
}
// Actions du menu principal
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = [Link]();
/* complete the code */
return [Link](item);
}
}