1. Avant de commencer
Les appareils Android sont disponibles dans un large éventail de formes, de tailles et de facteurs de forme. Vous devez concevoir votre application pour qu'elle s'exécute sur ces différents types d'appareils, quelle que soit la taille de l'écran. Il se peut que les développeurs qui créent des applications prêtes pour la production acceptent Android Wear, Android Auto et Android TV. Cependant, ces sujets ne sont pas abordés dans ce cours. Lorsque votre application est compatible avec la plus grande variété d'écrans possible, vous pouvez la rendre accessible à un maximum d'utilisateurs sur différents appareils.
Votre application doit présenter une mise en page flexible. Au lieu de définir une mise en page avec des dimensions rigides qui nécessitent un format et une taille d'écran donnés, vous devez faire en sorte qu'elle s'adapte facilement à différentes orientations et tailles d'écran. Le même principe s'applique lorsque votre application s'exécute sur un appareil pliable, dont la taille d'écran et le format peuvent changer en cours d'exécution. À la fin de cet atelier de programmation, nous vous proposerons une brève présentation des appareils pliables.
Conditions préalables
- Vous êtes capable de télécharger du code dans Android Studio et de l'exécuter.
- Vous maîtrisez les composants d'architecture Android
ViewModel
etLiveData
. - Vous avez une connaissance de base des composants de navigation.
Points abordés
- Comment ajouter
SlidingPaneLayout
à votre application.
Objectifs de l'atelier
- Mettre à jour l'application "Sports" pour l'adapter aux écrans de grande taille.
Ce dont vous avez besoin
- Un ordinateur sur lequel est installé Android Studio
- Le code de démarrage de l'application Sports
Télécharger le code de démarrage pour cet atelier de programmation
Cet atelier de programmation fournit un code de démarrage que vous pouvez étendre avec les fonctionnalités qui y sont enseignées. Le code de démarrage peut contenir du code que vous avez déjà vu dans les ateliers de programmation précédents, ainsi que du code inconnu qui sera présenté dans les ateliers suivants.
Pour télécharger le code de cet atelier de programmation à partir de GitHub et l'ouvrir dans Android Studio, procédez comme suit :
- Lancez Android Studio.
- Dans la fenêtre Bienvenue dans Android Studio, cliquez sur Obtenir à partir de VCS.
- Dans la boîte de dialogue Obtenir à partir du contrôle des versions, assurez-vous que Git est sélectionné pour Contrôle des versions.
- Collez l'URL du code fourni dans le champ URL.
- Vous pouvez également indiquer une valeur autre que la suggestion par défaut dans le champ Répertoire.
- Cliquez sur Clone (Cloner). Android Studio commence à récupérer votre code.
- Attendez qu'Android Studio s'ouvre.
- Sélectionnez le module approprié pour le code de solution, d'application ou de démarrage de votre atelier de programmation.
- Cliquez sur le bouton Run (Exécuter) pour créer et exécuter votre code.
2. Regarder la vidéo du code pas à pas (facultatif)
Si vous souhaitez voir un formateur réaliser cet atelier de programmation, regardez la vidéo ci-dessous.
Nous vous recommandons d'afficher la vidéo en plein écran (à l'aide de l'icône dans l'angle inférieur droit de la vidéo) pour mieux voir Android Studio et le code.
Cette étape est facultative. Vous pouvez également ignorer la vidéo et passer immédiatement aux instructions de l'atelier de programmation.
3. Présentation de l'application de démarrage
L'application "Sports" se compose de deux écrans. Le premier affiche la liste des sports. L'utilisateur peut sélectionner un sport en particulier. Le deuxième écran s'affiche alors. Il s'agit d'un écran d'informations qui affiche les actualités des sports sélectionnés. Cet écran d'informations affiche un texte d'espace réservé pour simplifier l'implémentation.
Explication du code de démarrage
Les mises en page de l'écran de liste et de l'écran d'informations sont prédéfinies dans le code de démarrage que vous avez téléchargé. Dans ce parcours, vous allez vous concentrer uniquement sur l'adaptation de votre application aux écrans de grande taille. Vous utiliserez SlidingPaneLayou
t pour tirer parti du grand écran. Voici une présentation rapide de certains fichiers pour vous aider à commencer.
fragment_sports_list.xml
- Ouvrez
res/layout/fragment_sports_list.xml
dans la vue Conception. - Ce fichier contient la mise en page du premier écran de votre application qui correspond à la liste des sports.
- Cette mise en page comprend une Recyclerview qui affiche une liste d'actualités sportives.
sports_list_item.xml
- Ouvrez
res/layout/sports_list_item.xml
dans la vue Conception. - Ce fichier contient la mise en page de chaque élément de Recyclerview.
- Cette mise en page comprend une vignette du sport, le titre Actualités et un texte d'espace réservé pour des actualités sportives en bref.
fragment_sports_news.xml
- Ouvrez
res/layout/fragment_sports_news.xml
dans la vue Conception. - Ce fichier contient la mise en page du deuxième écran de votre application. Cet écran s'affiche lorsque l'utilisateur sélectionne un sport dans Recyclerview.
- Cette mise en page se compose d'une bannière d'image de sport et d'un texte d'espace réservé pour les actualités sportives.
main_activity.xml et content_main.xml
Ces deux fichiers définissent la disposition d'activité principale avec un seul fragment.
navigation/nav_graph.xml
Le graphique de navigation contient deux destinations, l'une pour les listes des sports et l'autre pour les actualités sportives.
dossier res/values
Vous connaissez les fichiers de ressources de ce dossier.
colors.xml
contient les couleurs du thème utilisées dans l'application.strings.xml
contient toutes les chaînes dont votre application a besoin.themes.xml
contient la personnalisation de l'interface utilisateur effectuée pour votre application.
MainActivity.kt
Ce fichier contient le code par défaut généré par le modèle pour définir la vue de contenu de l'activité en tant que main_activity.xml
. La méthode onSupportNavigateUp()
est ignorée afin de gérer la navigation vers le haut par défaut depuis la barre d'application.
model/Sport.kt
Il s'agit d'une classe de données qui contient les données à afficher dans chaque ligne de la Recyclerview de la liste des sports.
data/SportsData.kt
Ce fichier contient une fonction appelée getSportsData()
qui renvoie un ArrayList
prérempli avec des données sportives codées en dur.
SportsViewModel.kt
Il s'agit du ViewModel
partagé pour l'application. ViewModel
est partagé par SportsListFragment
, le premier écran avec la liste des sports, et NewsDetailsFragment
, le deuxième écran avec les actualités sportives détaillées.
- La propriété
_currentSport
est de typeMutableLiveData,
, qui stocke le sport sélectionné par l'utilisateur. La propriétécurrentSport
est la propriété de support pour_currentSport
. Elle est exposée en tant que version publique en lecture seule pour les autres classes. - La propriété
_sportsData
contient la liste des données sportives.sportsData
est semblable à la propriété précédente. Il s'agit de la version publique en lecture seule de cette propriété. - Le bloc d'initialisation
init{}
initialise_currentSport
et_sportsData
._sportsData
est initialisé avec la liste complète des sports provenant dedata/SportsData.kt
._currentSport
est initialisé avec le premier élément de la liste. - La fonction
updateCurrentSport()
utilise une instanceSports
et met à jour_currentSport
avec la valeur transmise.
SportsAdapter.kt
Il s'agit de l'adaptateur pour RecyclerView
. Dans le constructeur, l'écouteur de clics est transmis. Le code de ce fichier est, en grande partie, un code récurrent que vous avez découvert lors d'ateliers de programmation précédents.
SportsListFragment.kt
Il s'agit du premier fragment d'écran où est affichée la liste des sports.
- La fonction
onCreateView()
gonfle le code XML de mise en pagefragment_sports_list
à l'aide de l'objet de liaison. - La fonction
onViewCreated()
configure l'adaptateurRecyclerView
. Elle met à jour le sport sélectionné par l'utilisateur comme étant le sport actuel dans leViewModel
partagé,SportsViewModel
. Elle permet d'accéder à l'écran d'informations contenant les actualités sportives et envoie la liste des sports à l'adaptateur pour l'afficher à l'aide desubmitList(List)
.
NewsDetailsFragment.kt
Il s'agit du deuxième écran de votre application, où est affiché un texte d'espace réservé pour les actualités sportives.
- La fonction
onCreateView()
gonfle le code XML de mise en pagefragment_sports_news
à l'aide de l'objet de liaison. - La fonction
onViewCreated()
associe un observateur à la propriété deSportsViewModel
,currentSport
, pour mettre à jour automatiquement l'interface utilisateur lorsque les données changent. Le titre, l'image et les actualités du sport sont mis à jour dans l'observateur.
Créer et exécuter l'application
- Créez et exécutez l'application sur un émulateur ou un appareil. Sélectionnez n'importe quel élément de la liste des sports. L'application devrait alors accéder au deuxième écran avec un texte d'espace réservé pour les actualités.
4. Schéma List-Detail
L'application de démarrage actuelle n'exploite pas tout l'espace d'affichage sur les appareils plus grands tels que les tablettes. Pour résoudre ce problème, vous allez afficher l'interface utilisateur de l'application à l'aide du schéma List-Detail, que vous découvrirez dans cet atelier de programmation.
Exécuter l'application sur une tablette
Dans cette tâche, vous allez créer un émulateur avec un profil pour tablette. Une fois l'émulateur créé, vous allez exécuter le code de démarrage de l'application "Sports" et observer l'interface utilisateur.
- Dans Android Studio, accédez à Outils > AVD Manager.
- La fenêtre Gestionnaire des appareils virtuels Android s'affiche. Cliquez sur + Créer un appareil virtuel… en bas de l'écran.
- La fenêtre Configuration de l'appareil virtuel s'affiche. Vous allez maintenant configurer le matériel et l'OS de l'émulateur. Cliquez sur Tablette dans le volet gauche. Sélectionnez Pixel C ou tout autre profil matériel similaire dans le volet central.
- Appuyez sur Suivant.
- Sélectionnez la dernière image système. Au moment de la rédaction de cet atelier de programmation, la dernière version était R (niveau d'API 30).
- Appuyez sur Suivant.
- Vous pouvez renommer l'appareil virtuel maintenant (cette étape est facultative).
- Cliquez sur Terminer.
- Vous revenez alors à la fenêtre Gestionnaire des appareils virtuels Android. Cliquez sur l'icône de lancement à côté du nouvel appareil virtuel.
- L'émulateur doté du profil pour tablette doit normalement se lancer. Veuillez patienter, cette opération peut prendre un certain temps.
- Fermez la fenêtre Gestionnaire des appareils virtuels Android.
- Exécutez l'application "Sports" sur le nouvel émulateur.
Notez que sur les appareils de grande taille, l'application n'utilise pas tout l'écran. Le schéma list-detail est plus efficace sur un grand écran qu'une liste. Un schéma item-detail (également appelé schéma master-detail) affiche une liste d'éléments sur un côté de la mise en page. Les détails s'affichent à côté lorsque vous appuyez sur un élément. En général, ces vues ne s'affichent que sur les grands écrans (des tablettes, par exemple), car elles offrent davantage d'espace pour le contenu.
Les images suivantes illustrent un exemple de schéma list-detail :
Les schémas list-detail ci-dessus affichent une liste d'éléments à gauche et des informations sur l'élément sélectionné à droite.
De la même manière, si vous utilisez le schéma ci-dessus dans votre application "Sports", le fragment d'actualités correspondra à l'écran d'informations.
Dans cet atelier de programmation, vous allez apprendre à implémenter l'interface utilisateur de list-detail à l'aide de SlidingPaneLayout
.
5. Schéma SlidingPaneLayout
Il se peut que l'interface utilisateur de list-detail doive se comporter différemment en fonction de la taille de l'écran. Sur les grands écrans, il y a suffisamment d'espace pour afficher les volets de liste et de détails côte à côte. Cliquez sur un élément de la liste pour afficher les informations correspondantes dans le volet de détails. Cependant, sur les petits écrans, on a l'impression qu'il n'y a pas suffisamment d'espace. Au lieu d'afficher les deux volets en même temps, il est préférable de les afficher un par un. Au départ, le volet de liste remplit tout l'écran. Appuyez sur un élément pour remplacer le volet de liste par le volet de détails, qui occupe également tout l'écran.
Vous allez apprendre à utiliser un modèle SlidingPaneLayout pour gérer la logique permettant de sélectionner l'expérience utilisateur appropriée en fonction de la taille d'écran actuelle.
Comme vous pouvez le voir, le volet de détails glisse par-dessus le volet de liste sur les petits écrans.
Les images ci-dessous montrent comment SlidingPaneLayout
apparaît sur un écran plus petit. Lorsqu'un élément de la liste est sélectionné, vous pouvez constater que le volet de détails chevauche le volet de liste. Les deux volets sont donc toujours présents.
Par conséquent, SlidingPaneLayout
permet d'afficher deux volets côte à côte sur les appareils plus grands, tout en s'adaptant automatiquement pour n'afficher qu'un seul volet à la fois sur les appareils plus petits tels que les téléphones.
6. Ajouter des dépendances de bibliothèque
- Ouvrez
build.gradle (Module: Sports.app)
. - Dans la section
dependencies
, incluez la dépendance suivante pour utiliserSlidingPaneLayout
dans votre application.
dependencies {
...
implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0-beta01"
}
7. Configurer le fichier XML du fragment de liste des sports
Dans cette tâche, vous allez convertir la mise en page racine de fragment_sports_list
en SlidingPaneLayout
. Comme vous l'avez déjà vu précédemment, SlidingPaneLayout
fournit une mise en page horizontale à deux volets à utiliser au niveau supérieur d'une interface utilisateur. Cette mise en page utilise le premier volet en tant que liste de contenu ou navigateur. Elle dépend d'une vue détaillée principale pour afficher du contenu dans l'autre volet.
Dans l'application "Sports", le premier volet correspond à la RecyclerView
qui affiche la liste des sports, tandis que le deuxième volet affiche les actualités sportives.
Ajouter SlidingPaneLayout
- Ouvrez
fragment_sports_list.xml
. Notez que la mise en page racine est unFrameLayout
. - Remplacez
FrameLayout
parandroidx.slidingpanelayout.widget.SlidingPaneLayout.
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SportsListFragment">
<androidx.recyclerview.widget.RecyclerView...>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
- Ajoutez un attribut
android:id
àSlidingPaneLayout
et attribuez-lui la valeur@+id/sliding_pane_layout
.
<androidx.slidingpanelayout.widget.SlidingPaneLayout
...
android:id="@+id/sliding_pane_layout"
...>
Ajouter un deuxième volet à SlidingPaneLayout
Dans cette tâche, vous allez ajouter un deuxième élément enfant à SlidingPaneLayout
. Il sera affiché en tant que volet de contenu de droite.
- Dans
fragment_sports_list.xml
, sousRecyclerView
, ajoutez un deuxième élément enfant,androidx.fragment.app.FragmentContainerView
. - Ajoutez les attributs obligatoires,
layout_height
etlayout_width
, àFragmentContainerView
. Attribuez-leur la valeurmatch_parent
. Notez que vous mettrez à jour ces valeurs ultérieurement.
<androidx.fragment.app.FragmentContainerView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
- Ajoutez un attribut
android:id
àFragmentContainerView
et attribuez-lui la valeur@+id/detail_container
.
android:id="@+id/detail_container"
- Ajoutez
NewsDetailsFragment
àFragmentContainerView
en utilisant l'attributandroid:name
.
android:name="com.example.android.sports.NewsDetailsFragment"
Mettre à jour l'attribut layout_width
SlidingPaneLayout
utilise la largeur des deux volets pour déterminer s'ils doivent être affichés côte à côte. Par exemple, si le volet de liste doit avoir une taille minimale de 300dp
et que le volet de détails a besoin de 400dp
, SlidingPaneLayout
affiche automatiquement les deux volets côte à côte, à condition que sa largeur disponible soit d'au moins 700dp
.
Les vues enfants se chevauchent si leur largeur combinée dépasse la largeur disponible dans SlidingPaneLayout
. Dans ce cas, les vues enfants sont agrandies pour remplir la largeur disponible dans SlidingPaneLayout
.
Pour déterminer la largeur des vues enfants, vous devez disposer d'informations de base sur la largeur d'écran des appareils. Le tableau suivant présente la liste de points d'arrêt permettant de concevoir, développer et tester des mises en page d'application redimensionnables. Ils ont été choisis spécialement pour trouver le juste équilibre entre la simplicité de mise en page et la souplesse d'optimisation de l'application en fonction de cas spécifiques.
Largeur | Point d'arrêt | Représentation de l'appareil |
Largeur compacte | < 600 dp | 99,96 % des téléphones en mode portrait |
Largeur moyenne | Plus de 600 dp | 93,73 % des tablettes en mode portrait. Grands écrans internes dépliés en mode portrait. |
Grande largeur | Plus de 840 dp | 97,22 % des tablettes en mode paysage. Grands écrans internes déployés en mode paysage. |
Dans l'application Sports, vous souhaitez afficher un seul volet, la liste des sports sur les téléphones, c'est-à-dire sur les appareils dont la largeur est inférieure à 600dp
. Pour afficher les deux volets sur des tablettes, la largeur combinée doit être supérieure à 840dp
. Vous pouvez utiliser une largeur de 550dp
pour le premier élément enfant, la vue recycleur, et une largeur de 300dp
pour le deuxième élément enfant, le FragmentContainerView
.
- Dans
fragment_sports_list.xml
, définissez la largeur de mise en page deRecyclerView
sur550dp
et celle deFragmentContainerView
sur300dp
.
<androidx.recyclerview.widget.RecyclerView
...
android:layout_width="550dp"
.../>
<androidx.fragment.app.FragmentContainerView
...
android:layout_width="300dp"
.../>
- Exécutez l'application sur un émulateur avec le profil de tablette et un émulateur avec le profil de téléphone.
Notez que deux volets sont affichés sur la tablette. Vous corrigerez la largeur du deuxième volet de la tablette à l'étape suivante.
- Exécutez l'application sur l'émulateur avec le profil de téléphone.
Ajouter layout_weight
Dans cette tâche, vous allez corriger l'interface utilisateur sur la tablette et faire en sorte que le deuxième volet occupe tout l'espace restant.
SlidingPaneLayout
permet de définir la façon dont l'espace restant est divisé après la mesure à l'aide du paramètre de mise en page layout_weight
sur les vues enfants si celles-ci ne se chevauchent pas. Ce paramètre s'applique uniquement à la largeur.
- Dans
fragment_sports_list.xml
, ajoutezlayout_weight
àFragmentContainerView
et attribuez-lui la valeur1
. Le deuxième volet est agrandi pour occuper l'espace restant après la mesure du volet de liste.
android:layout_weight="1"
- Exécutez l'application.
Félicitations ! Vous avez ajouté SlidingPaneLayout
. Cependant, vous n'avez pas encore terminé. Vous devez encore implémenter la navigation vers l'arrière et mettre à jour le deuxième volet lorsqu'un élément est sélectionné dans la liste. Vous effectuerez ces opérations lors d'une tâche ultérieure.
8. Remplacer le volet de vue détaillée
Exécutez l'application sur l'émulateur avec le profil de tablette. Sélectionnez un élément dans la liste "Sports". Notez que l'application accède au volet de détails.
Dans cette tâche, vous allez résoudre ce problème. Le contenu du double volet est en cours de mise à jour avec le sport sélectionné. L'application accède ensuite à NewsDetailsFragment
.
- Dans le fichier
SportsListFragment
, dans la fonctiononViewCreated()
, recherchez les lignes suivantes qui permettent d'accéder à l'écran d'informations.
// Navigate to the details screen
val action = SportsListFragmentDirections.actionSportsListFragmentToNewsFragment()
this.findNavController().navigate(action)
- Remplacez les lignes ci-dessus par le code suivant :
binding.slidingPaneLayout.openPane()
Appelez openPane()
sur SlidingPaneLayout
pour permuter les deux volets. Cela n'aura aucun effet visible si les deux volets sont affichés, comme c'est le cas sur une tablette.
- Exécutez l'application sur l'émulateur de tablette et de téléphone. Notez que le contenu du double volet est mis à jour correctement.
Votre prochaine tâche consistera à enrichir l'application d'une fonctionnalité de navigation vers l'arrière personnalisée.
9. Ajouter la navigation vers l'arrière personnalisée
Pour les appareils de plus petite taille sur lesquels les volets de liste et de détails se chevauchent, assurez-vous que le bouton "Retour" du système fait revenir l'utilisateur du volet de détails au volet de liste. Pour ce faire, fournissez une navigation vers l'arrière personnalisée et connectez un OnBackPressedCallback
à l'état actuel de SlidingPaneLayout
.
Navigation vers l'arrière
La navigation vers l'arrière permet aux utilisateurs de revenir en arrière dans l'historique des écrans qu'ils ont déjà consultés. Tous les appareils Android proposent un bouton "Retour" pour ce type de navigation. En fonction de l'appareil Android de l'utilisateur, il peut s'agir d'un bouton physique ou d'un bouton logiciel.
Navigation vers l'arrière personnalisée
Android conserve une pile "Retour" des destinations à mesure que l'utilisateur parcourt l'application. Cela permet généralement à Android de revenir correctement aux destinations précédentes lorsque l'utilisateur appuie sur le bouton "Retour". Toutefois, dans certains cas, il se peut que votre application doive implémenter son propre comportement "Retour" afin d'offrir la meilleure expérience utilisateur possible.
Par exemple, lors de l'utilisation d'une WebView telle qu'un navigateur Chrome, vous pouvez ignorer le comportement par défaut du bouton Retour pour permettre à l'utilisateur de revenir en arrière dans son historique de navigation Web au lieu des écrans précédents de votre application.
De même, vous devez fournir une navigation vers l'arrière personnalisée vers SlidingPaneLayout
et parcourir l'application à partir du volet de détails jusqu'au volet de liste.
Implémenter la navigation vers l'arrière personnalisée
Pour implémenter la navigation vers l'arrière personnalisée dans votre application "Sports", vous devez :
- Définir un rappel personnalisé pour gérer l'utilisation de la touche Retour, ce qui remplace
OnBackPressedCallback
. - Enregistrer et ajouter l'instance de rappel.
Commencez par définir le rappel personnalisé.
- Dans le fichier
SportsListFragment
, ajoutez une classe sous la définition de classeSportsListFragment
. Nommez-laSportsListOnBackPressedCallback
. - Transmettez une instance
private
deSlidingPaneLayout
en tant que paramètre constructeur.
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
)
- Étendez la classe depuis
OnBackPressedCallback
. La classeOnBackPressedCallback
gère les rappelsonBackPressed
. Vous allez bientôt corriger l'erreur liée au paramètre constructeur.
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
): OnBackPressedCallback()
Le constructeur de OnBackPressedCallback
utilise une valeur booléenne pour l'état initial activé. C'est seulement quand un rappel est activé (isEnabled()
renvoie la valeur "true") que le dispatcher appelle la méthode handleOnBackPressed()
du rappel pour gérer l'événement du bouton "Retour".
- Transmettez
slidingPaneLayout.
isSlideable
*&& slidingPaneLayout.isOpen
* en tant que paramètre constructeur àOnBackPressedCallback
. La valeur booléenneisSlideable
n'est définie sur "true" que s'il est possible de faire glisser le deuxième volet, c'est-à-dire sur un écran de plus petite taille où un seul volet est affiché. La valeur deisOpen
seratrue
si le deuxième volet (le volet de contenu) est entièrement ouvert.
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
): OnBackPressedCallback(slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen)
Ce code garantit que le rappel n'est activé que sur les appareils dotés d'un écran de petite taille et lorsque le volet de contenu est ouvert.
- Pour corriger l'erreur concernant la méthode non implémentée, cliquez sur l'ampoule rouge , puis sélectionnez Implémenter les membres.
- Cliquez sur OK dans la fenêtre pop-up Implémenter les membres pour ignorer la méthode
handleOnBackPressed
.
Votre classe doit se présenter comme suit :
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
): OnBackPressedCallback(slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen) {
/**
* Callback for handling the [OnBackPressedDispatcher.onBackPressed] event.
*/
override fun handleOnBackPressed() {
TODO("Not yet implemented")
}
}
- Dans la fonction
handleOnBackPressed()
, supprimez l'instruction TODO, puis ajoutez le code suivant pour fermer le volet de contenu et revenir au volet de liste.
slidingPaneLayout.closePane()
Surveiller les événements de SlidingPaneLayout
En plus de gérer les événements de navigation vers l'arrière, vous devez écouter et surveiller les événements liés au volet coulissant. Lorsque l'utilisateur fait glisser le volet de contenu, le rappel doit être activé ou désactivé en conséquence. Pour ce faire, utilisez PanelSlideListener
.
L'interface SlidingPaneLayout.PanelSlideListener
contient trois méthodes abstraites : onPanelSlide()
, onPanelOpened()
et onPanelClosed()
. Ces méthodes sont appelées lorsque l'utilisateur fait glisser, ouvre et ferme le volet de détails.
- Étendez la classe
SportsListOnBackPressedCallback
depuisSlidingPaneLayout.PanelSlideListener
. - Pour résoudre l'erreur, implémentez les trois méthodes. Cliquez sur l'ampoule rouge, puis sélectionnez Implémenter les membres dans Android Studio.
- Votre classe
SportsListOnBackPressedCallback
doit se présenter comme suit :
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
): OnBackPressedCallback(slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen),
SlidingPaneLayout.PanelSlideListener{
override fun handleOnBackPressed() {
slidingPaneLayout.closePane()
}
override fun onPanelSlide(panel: View, slideOffset: Float) {
TODO("Not yet implemented")
}
override fun onPanelOpened(panel: View) {
TODO("Not yet implemented")
}
override fun onPanelClosed(panel: View) {
TODO("Not yet implemented")
}
}
- Supprimez les instructions TODO.
- Activez le rappel
OnBackPressedCallback
lorsque le volet de détails est ouvert (c'est-à-dire lorsqu'il est visible). Pour ce faire, vous pouvez appeler la fonctionsetEnabled()
et transmettretrue
. Écrivez le code suivant dansonPanelOpened()
:
setEnabled(true)
- Le code ci-dessus peut être simplifié à l'aide de la syntaxe d'accès aux propriétés.
override fun onPanelOpened(panel: View) {
isEnabled = true
}
- De même, définissez
isEnabled
surfalse
, lorsque le volet de détails est fermé.
override fun onPanelClosed(panel: View) {
isEnabled = false
}
- La dernière étape d'exécution du rappel consiste à ajouter la classe d'écouteur
SportsListOnBackPressedCallback
à la liste des écouteurs qui sont informés lorsque l'utilisateur fait glisser le volet de détails. Ajoutez un blocinit
à la classeSportsListOnBackPressedCallback
. Dans le blocinit
, appelezslidingPaneLayout.addPanelSlideListener()
en transmettantthis
.
init {
slidingPaneLayout.addPanelSlideListener(this)
}
La classe SportsListOnBackPressedCallback
terminée doit se présenter comme suit :
class SportsListOnBackPressedCallback(
private val slidingPaneLayout: SlidingPaneLayout
): OnBackPressedCallback(slidingPaneLayout.isSlideable && slidingPaneLayout.isOpen),
SlidingPaneLayout.PanelSlideListener{
init {
slidingPaneLayout.addPanelSlideListener(this)
}
override fun handleOnBackPressed() {
slidingPaneLayout.closePane()
}
override fun onPanelSlide(panel: View, slideOffset: Float) {
}
override fun onPanelOpened(panel: View) {
isEnabled = true
}
override fun onPanelClosed(panel: View) {
isEnabled = false
}
}
Enregistrer le rappel
Pour voir votre rappel en action, enregistrez-le à l'aide du dispatcher, OnBackPressedDispatcher
.
La classe de base de FragmentActivity
vous permet de contrôler le comportement du bouton "Retour" en utilisant son OnBackPressedDispatcher
. OnBackPressedDispatcher
contrôle la façon dont les événements du bouton "Retour" sont envoyés à un ou plusieurs objets OnBackPressedCallback
.
Ajoutez le rappel à l'aide de la méthode addCallback()
. Cette méthode utilise un objet LifecycleOwner
. Cela vous aide à assurer que OnBackPressedCallback
n'est ajouté que lorsque LifecycleOwner
est défini sur Lifecycle.State.STARTED
. L'activité ou le fragment supprime également les rappels enregistrés lorsque le LifecycleOwner
associé est détruit. Cela permet d'éviter les fuites de mémoire et de faire en sorte qu'il puisse être utilisé dans des fragments ou d'autres propriétaires de cycle de vie ayant une durée de vie plus courte.
La méthode addCallback()
utilise également l'instance de classe de rappel en tant que deuxième paramètre. Pour enregistrer le rappel, procédez comme suit :
- Dans le fichier
SportsListFragment
, dans la fonctiononViewCreated()
, en dessous de la déclaration de la variable de liaison, créez une instance pourSlidingPaneLayout
et attribuez-lui la valeurbinding.slidingPaneLayout
.
val slidingPaneLayout = binding.slidingPaneLayout
- Dans le fichier
SportsListFragment
, dans la fonctiononViewCreated()
, en dessous de la déclaration deslidingPaneLayout
, ajoutez le code suivant :
// Connect the SlidingPaneLayout to the system back button.
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
SportsListOnBackPressedCallback(slidingPaneLayout)
)
Le code ci-dessus utilise addCallback()
, en transmettant viewLifecycleOwner
et une instance de SportsListOnBackPressedCallback
. Ce rappel n'est actif que pendant le cycle de vie du fragment.
- Il est maintenant temps d'exécuter l'application sur un émulateur avec un profil de téléphone et de voir comment fonctionne le bouton "Retour" personnalisé.
10. Mode verrouillé
Lorsque les volets de liste et de détails se chevauchent sur des écrans plus petits, comme des téléphones, les utilisateurs peuvent, par défaut, balayer l'écran dans les deux sens et basculer librement entre les deux volets, même s'ils n'utilisent pas la navigation par gestes. Vous pouvez verrouiller ou déverrouiller le volet de détails en définissant le mode verrouillé de SlidingPaneLayout
.
- Dans l'émulateur avec le profil de téléphone, balayez le volet de détails pour le faire sortir de l'écran.
- Vous pouvez également balayer le volet Détails pour qu'il s'affiche à l'écran. Essayez par vous-même.
- Cette fonctionnalité n'est pas souhaitable dans votre application Sports. Il est recommandé de verrouiller
SlidingPaneLayout
pour empêcher tout mouvement de balayage à l'aide de gestes. Pour implémenter cela, dans la méthodeonViewCreated()
, sous la définitionslidingPaneLayout
, définissezlockMode
surLOCK_MODE_LOCKED
:
slidingPaneLayout.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
Pour en savoir plus sur les autres modes de verrouillage, veuillez consulter la documentation.
- Exécutez à nouveau l'application. Comme vous pouvez le constater, le volet de détails est maintenant verrouillé.
Félicitations ! Vous avez ajouté SlidingPaneLayout
à votre application.
11. Code de solution
Le code de solution de cet atelier de programmation figure dans le projet et le module ci-dessous.
- Accédez à la page du dépôt GitHub fournie pour le projet.
- Vérifiez que le nom de la branche correspond à celui spécifié dans l'atelier de programmation. Par exemple, dans la capture d'écran suivante, le nom de la branche est main.
- Sur la page GitHub du projet, cliquez sur le bouton Code pour afficher une fenêtre pop-up.
- Dans la fenêtre pop-up, cliquez sur le bouton Download ZIP (Télécharger le fichier ZIP) pour enregistrer le projet sur votre ordinateur. Attendez la fin du téléchargement.
- Recherchez le fichier sur votre ordinateur (il se trouve probablement dans le dossier Téléchargements).
- Double-cliquez sur le fichier ZIP pour le décompresser. Un dossier contenant les fichiers du projet est alors créé.
Ouvrir le projet dans Android Studio
- Lancez Android Studio.
- Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur Open (Ouvrir).
Remarque : Si Android Studio est déjà ouvert, sélectionnez l'option de menu File > Open (Fichier > Ouvrir).
- Dans l'explorateur de fichiers, accédez à l'emplacement du dossier du projet décompressé (il se trouve probablement dans le dossier Téléchargements).
- Double-cliquez sur le dossier de ce projet.
- Attendez qu'Android Studio ouvre le projet.
- Cliquez sur le bouton Run (Exécuter) pour créer et exécuter l'application. Assurez-vous qu'elle fonctionne correctement.