0% ont trouvé ce document utile (0 vote)
33 vues32 pages

1 AndroidRouter

Le document explique comment changer le contenu d'un composant dans une application Android en utilisant un mécanisme de routeur et de navigation. Il présente l'utilisation de NavHost et NavController de Jetpack Compose pour gérer les écrans et les transitions entre eux, ainsi que des exemples de boutons et d'icônes pour naviguer entre les écrans. Enfin, il aborde l'intégration de la navigation avec des barres de navigation et un Floating Action Button (FAB).

Transféré par

abdelkader maatallah
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
33 vues32 pages

1 AndroidRouter

Le document explique comment changer le contenu d'un composant dans une application Android en utilisant un mécanisme de routeur et de navigation. Il présente l'utilisation de NavHost et NavController de Jetpack Compose pour gérer les écrans et les transitions entre eux, ainsi que des exemples de boutons et d'icônes pour naviguer entre les écrans. Enfin, il aborde l'intégration de la navigation avec des barres de navigation et un Floating Action Button (FAB).

Transféré par

abdelkader maatallah
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Cedric Dumoulin

Ou comment changer le contenu d’un composant


Comprendre le problème
 1 Activity
 Le composant principal doit changer en fonction de la navigation
 Navigation == click sur un bouton ou lien pour afficher un autre écran
 Ici, 3 écrans, dont un avec un paramétre

Activity

Screen 3

Screen 1 Screen 2

Screen 3
Solution
Mécanisme de routeur ou d’aiguillage
 Un mécanisme de routeur se charge d’afficher le composant requis
 Ce mécanisme est implémenté dans un composant ‘routeur’
 Le routeur connait tous les composants affichables
 Chaque composant est associé à un id ou un ‘path’
 Le routeur choisit le composant
 en fonction du path ou de l’id demandé

choix=screen1
Routeur

path=screen1 path=screen2 path=screen3/{year}


Solution
Mécanisme de navigation
 Un mécanisme de navigation permet de changer le
path ou l’id
 Et donc de changer le composant affiché

Mécanisme
de navigation
choix=screen2
Routeur

path=screen1 path=screen2 path=screen3/{year}


Router avec Compose
 Android Compose propose un mécanisme de router et
de navigation :
 Router : NavHost
 Navigation : [Link]
 Navigating with Compose
 [Link]
tion#samples
Sélection des composants avec
NavHost Instanciation du
mécanisme de
navigation
val navController = rememberNavController()

Le mécanisme
Composant
de navigation Route de départ
Routeur
associé

NavHost(navController = navController, startDestination = "profile") {


composable("profile") { Profile(/*...*/) }
composable("friendslist") { FriendsList(/*...*/) }
/*...*/
}
Liste des routes:
composable( path ) { Composant() }
Instanciation du NavController
 Le NavController permet de faire la navigation
 [Link](« destination »);
 Il faut l’instancier avant de l’utiliser.
 Instanciation dans un des composants parents
 Souvent au sommet de l’arbre des composants
 Passage aux composants enfants
 En tant que parametre

val navController = rememberNavController()

// Create navigation Actions


val navigationActions = remember(navController) {
NavigationActions(navController)
}

AppScaffold(navController, modifier, navigationActions)


Navigation
Ou comment changer le composant sélectionné
 Utiliser [Link]( « new route »)
 La nouvelle route est mise sur la pile des routes
 Pour pouvoir faire un back
 On peut manipuler la pile
 Pour éviter les doublons, eviter de mettre plusieurs fois la même route

Dépile toute les routes jusque
la route de départ.
➔ On sera juste après
[Link](«screen2») { Une seule route de ce type sur
le sommet (si la route est déjà
popUpTo([Link]().id) { au sommet, ne fait rien).
saveState = true
} Indique de récupérer les
launchSingleTop = true valeurs états précedent pour
ce composant
restoreState = true
} Actions exécutées avant
l’empilement de la route
Créer un bouton ou une icone de navigation
Solution avec NavHostController
 Passer le NavHostController en parametre
 Appeler [Link](«newroute »)

@Composable
fun Screen4(modifier: Modifier = Modifier, navController : NavHostController) {
Column {

Text(text = "Hello the worlds, screen 1")

Button(
onClick = {[Link]("screen2")}
){
Text(text = "See friends list")
}
}

}
Créer une icone de navigation
Solution avec NavHostController
 Passer le NavHostController en parametre
 Appeler [Link](«newroute »)

IconButton(onClick = {[Link]("screen2")} ) {
Icon(
imageVector = [Link],
contentDescription = "Home"
)
}
Créer un bouton ou une icone de navigation
Solution avec fonction de navigation
 Passer une fonction de navigation en paramètre
 Utiliser la fonction
NavHost(navController = navController, startDestination = AppDestinations.SCREEN1) {
Déclaration de la fonction et
composable("screen4") {
passage au composant
var onNavigateToScreen2 = {[Link]("screen2")}

Screen4(modifier = modifier, onNavigateToScreen2 = onNavigateToScreen2)


}

@Composable
fun Screen4(modifier: Modifier = Modifier, onNavigateToScreen2: () -> Unit) {
Column {
Fonction de navigation en
Button(onClick = onNavigateToScreen2) { paramètre
Text(text = "See friends list")
} Appel de la fonction de
} navigation
}
Créer un bouton ou une icone de navigation
Solution avec classe NavigationsActions
 On regroupe les fonctions de navigation dans une classe
 On instancie la classe juste après l’instance du navController
 On passe l’instance de la classe aux composants
 On peut prévoir plusieurs classes de NavigationActions
Les routes sous forme de
object AppDestinations { constantes
const val SCREEN1 = "screen1"
const val SCREEN2 = "screen2"
}
class NavigationActions(navController: NavHostController) {
val navigateToScreen1: () -> Unit = {
[Link](AppDestinations.SCREEN1) {
// Pop up to the start destination of the graph to avoid building up a large stack of
// destinations on the back stack as users select items
popUpTo([Link]().id) {
saveState = true
}
// Avoid multiple copies of the same destination when reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true Les options de gestion de la
} pile
}
Créer un bouton ou une icone de navigation
Solution avec classe NavigationsActions (suite classe)

val navigateToScreen2: () -> Unit = {
[Link](AppDestinations.SCREEN2) {
popUpTo([Link]().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
var navigateToScreen3: (year : Int) -> Unit = {year ->
[Link](AppDestinations.SCREEN3 + "/" + year) {
Log.i("cdm", AppDestinations.SCREEN3 + "/" + year)
popUpTo([Link]().id) {
saveState = true
}
launchSingleTop = true Exemple avec passage de
//restoreState = true paramètre au composant
}
}
var navigateToHome: () -> Unit = navigateToScreen1

}
Créer un bouton ou une icone de navigation
Solution avec classe NavigationsActions (instanciation)

fun MainComponent(name: String, modifier: Modifier = Modifier) {

val navController = rememberNavController()


// Create navigation Actions
val navigationActions = remember(navController) { Instanciation de la classe
NavigationActions(navController) NavigationActions après
} l’instanciation du navController

AppScaffold(navController, modifier, navigationActions)


}
Créer un bouton ou une icone de navigation
Solution avec classe NavigationsActions (bouton)
fun AppRouter( Passage de navigationActions en
navController: NavHostController, paramétre
modifier: Modifier,
navigationActions: NavigationActions
){
NavHost(navController = navController, startDestination = AppDestinations.SCREEN1) {
composable(AppDestinations.SCREEN2) {
Screen2(modifier = modifier, navigationActions = navigationActions)
}
} Passage de la classe

@Composable
fun Screen2(modifier: Modifier = Modifier, navigationActions: NavigationActions) {
Column {
Button(onClick = navigationActions.navigateToScreen1) { Utilisation de la classe
Text(text = "See Screen 1")
}
Button(onClick = { navigationActions.navigateToScreen3(2024) })
{ Text(text = "2024") }
Button(onClick = { navigationActions.navigateToScreen3(2020) })
{ Text(text = "2020") }
}
}
Naviguer vers un composant
En lui passant des paramètres de type primitifs
 On peut passer des arguments de type primitif au
composant vers lequel on va naviguer
 On passe les valeurs dans le path
 path/{nonDeLaValeur}
 ➔on doit pouvoir convertir les valeurs en String

composable( Déclaration du chemin avec une variable ‘year’


AppDestinations.SCREEN3 + "/{year}",
arguments = listOf(navArgument("year") { type = [Link] })
)
Déclaration de la liste des arguments et
{ backStackEntry ->
de leurs type
val year = [Link]?.getInt("year")
Récupération de la valeur de l’argument
Screen3(
modifier = modifier, navigationActions = navigationActions,
year = year )
)
} Passage de l’argument au composant
Naviguer vers un composant
En lui passant des paramètres de type primitifs
 Lors de la navigation, il faut construire une URL avec
l’argument dans l’URL
 ➔ convertir l’argument en String

val year = 2023


[Link](« screen3 » + "/" + year)
Naviguer vers un composant
En lui passant des paramètres de type complexe
 Complexe == Class
 Ce n’est pas recommandé avec Compose et le Router
 [Link]
vigation#retrieving-complex-data
 Alternative :
 Passer un identifiant de type primitif en paramètre
 Dans le composant cible, rechercher l’objet à l’aide de
son identifiant
 Recherche dans la DB, sur un serveur …
Arbre des pseudo composants
 L’ensemble de vos (pseudo-)composants forme un
arbre
 Racine :
 Le composant appelé dans onCreate()

MainComponent

AppScaffold

MyTopNavBar MyBottonNavBar AppRouter

{Un des trois}

Screen1 Screen2 Screen3


Problème Barre de navigation

 Les applications ont


Contenu de
souvent la page
 une barre de navigation en
haut ou en bas, ou les
deux.
 Un bouton FAB (Floting
Action Button)
 Les barres de navigation
FAB
sont les même pour tous les
écrans
Barre de navigation
Composant spécialisé
 On utilise un composant qui prend en charge le
placement et le contrôle :
 Des barres de navigation
 Du FAB
 Du contenu

AppScaffold

MyTopNavBar MyBottonNavBar Contenu FAB


Composant Scaffold
Pour avoir des navbars et un contenu
 [Link]

fun AppScaffold(
navController: NavHostController,
modifier: Modifier, Scaffold prend 4
){ arguments :
Scaffold( - topBar
topBar = MyTopBar() - bottomBar
bottomBar = MyBottomBar
floatingActionButton = {
- FAB
FloatingActionButton(onClick = { presses++ }) { - Content
Icon([Link], contentDescription = "Add")
}
}
)
{innerPadding ->
Column(
modifier = [Link](innerPadding)
){
Text(text = « My content")
}
}
NavBar
Pour définir une TopAppBar(
colors = [Link](

barre de navigation ),
containerColor = [Link],
titleContentColor = [Link],

title = {
Text("Top app bar")
},
navigationIcon = {
IconButton(onClick = { /* do something */ }) {
Icon(
imageVector = [Link],
contentDescription = "Go Back"
)
}
},
 [Link] actions = {
pack/compose/components/app- IconButton(onClick = { /* do something */ }) {
bars Icon(
 TopAppBar imageVector = [Link],
 On peut spécifier : contentDescription = "Menu"
 Un titre )
 Une icone de navigation }
IconButton(onClick = [Link]) {
 Des Actions Icon(
 … imageVector = [Link],
contentDescription = "Home"
)
}
},
)
NavBar
Pour définir une BottomAppBar(
containerColor = [Link],
contentColor = [Link],
barre de navigation
){
Text(
modifier = Modifier,
textAlign = [Link],
text = "Bottom app bar",
)

IconButton(onClick = [Link]) {
Icon(
imageVector = [Link],
 [Link] contentDescription = "Home"
om/jetpack/compose/comp )
onents/app-bars }
Text(
 BottomAppBar textAlign = [Link],
 On peut spécifier : text = "text2",
)
 Un contenu, dans lequel on
}
met des icons de navigation
FAB (Floating Action Button)

FloatingActionButton(onClick = { presses++ }) {
Icon([Link], contentDescription = "Add")
}
Integration Scaffold, Router …
 Bien séparer chaque composant :
 MainRouter
 Et classe RouterActions
 MainScaffold
 MainTopBar, MainBottomBar, MainFloatingButton
 Vous pouvez ajouter MainSliderMenu
 Pas vu en TD
MainActivity

MainComponent

MainScaffold

MainTopBar MainBottonBar MainRouter

{Un des trois}

Screen1 Screen2 Screen3


Integration Scaffold, Router …
fun MainComponent(modifier: Modifier = Modifier) {

val navController = rememberNavController()


// Create navigation Actions
val navigationActions = remember(navController) {
fun MainScaffold(
NavigationActions(navController)
navController: NavHostController,
}
modifier: Modifier,
navigationActions : NavigationActions
){ MainScaffold(navController, modifier, navigationActions)
Scaffold( }
topBar = { MainTopBar(navigationActions) }
bottomBar = { MainBottomBar(navigationActions) }
floatingActionButton =
{MainFloatingButton(navigationActions) }
}
)
{innerPadding ->
Column(
modifier = [Link](innerPadding)
){
MainRouter(navigationActions)
}
}
Atelier
 Réalisation d’une application ‘multiScreens’ avec :
 4 écrans différents (home, screen1 à screen3)
 Chaque écran à un bouton permettant de passer à l’écran suivant ou précédent
 Un des écrans prend un paramètre de type int, et affiche sa valeur.
 Une topbar
 Permettant de naviguer vers l’écran home
 Une bottomBar
 Permettant de naviguer vers l’écran home et screen2

 Les écrans doivent être sous la forme de composant, chacun dans un


module
 Le composant effectuant le changement d’écran doit être réutilisable
(dans un Composable) et dans un module.

 Plus tard nous allons modéliser ce genre d’application


fun MainScaffold(
navController: NavHostController,
modifier: Modifier,
navigationActions : NavigationActions
){
Scaffold(
topBar = { MainTopBar(navigationActions) }
bottomBar = { MainBottomBar(navigationActions) }
floatingActionButton = {MainFloatingButton(navigationActions) }
}
)
{innerPadding ->
Column(
modifier = [Link](innerPadding)
){
MainRouter(navigationActions)
}
}

Vous aimerez peut-être aussi