Les boutons d'icône affichent les actions que les utilisateurs peuvent effectuer. Les boutons d'icône doivent utiliser une icône dont la signification est claire et représentent généralement des actions courantes ou fréquemment utilisées.
Il existe deux types de boutons d'icône :
- Par défaut : ces boutons peuvent ouvrir d'autres éléments, comme un menu ou une recherche.
- Bouton d'activation/désactivation : ces boutons peuvent représenter des actions binaires qui peuvent être activées ou désactivées, comme "favori" ou "signet".
Surface d'API
Utilisez le composable IconButton pour implémenter des boutons d'icône standards. Pour créer différents styles visuels tels que "filled", "filled tonal" ou "outlined", utilisez respectivement FilledIconButton, FilledTonalIconButton et OutlinedIconButton.
Les paramètres clés de IconButton sont les suivants :
onClick: fonction lambda qui s'exécute lorsque l'utilisateur appuie sur le bouton d'icône.enabled: valeur booléenne qui contrôle l'état d'activation du bouton. Lorsque la valeur estfalse, le bouton ne répond pas aux entrées de l'utilisateur.content: contenu composable à l'intérieur du bouton, généralement unIcon.
Exemple de base : bouton d'icône d'activation/désactivation
Cet exemple montre comment implémenter un bouton d'icône d'activation/désactivation. Un bouton d'icône d'activation/désactivation change d'apparence selon qu'il est sélectionné ou non.
@Preview @Composable fun ToggleIconButtonExample() { // isToggled initial value should be read from a view model or persistent storage. var isToggled by rememberSaveable { mutableStateOf(false) } IconButton( onClick = { isToggled = !isToggled } ) { Icon( painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite), contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button." ) } }
Points clés concernant le code
- Le composable
ToggleIconButtonExampledéfinit unIconButtonactivable/désactivable.mutableStateOf(false)crée un objetMutableStatequi contient une valeur booléenne, initialementfalse.isToggleddevient ainsi un conteneur d'état, ce qui signifie que Compose recompose l'UI chaque fois que sa valeur change.rememberSaveablegarantit que l'étatisToggledpersiste lors des modifications de configuration, comme la rotation de l'écran.
- Le lambda
onClickdeIconButtondéfinit le comportement du bouton lorsqu'un utilisateur clique dessus, en basculant l'état entretrueetfalse. - Le paramètre
painterdu composableIconcharge de manière conditionnelle unpainterResourcedifférent en fonction de l'étatisToggled. Cela modifie l'apparence visuelle de l'icône.- Si
isToggledest défini surtrue, il charge l'élément drawable en forme de cœur plein. - Si
isToggledest défini surfalse, il charge l'élément drawable en forme de cœur.
- Si
- La
contentDescriptiondeIconest également mise à jour en fonction de l'état deisToggledpour fournir les informations d'accessibilité appropriées.
Résultat
L'image suivante montre le bouton d'icône d'activation/désactivation de l'extrait précédent dans son état non sélectionné :
Exemple avancé : actions répétées lors d'un appui
Cette section explique comment créer des boutons d'icône qui déclenchent une action en continu lorsque l'utilisateur appuie de manière prolongée dessus, plutôt que de la déclencher une seule fois par clic.
@Composable fun MomentaryIconButton( unselectedImage: Int, selectedImage: Int, contentDescription: String, modifier: Modifier = Modifier, stepDelay: Long = 100L, // Minimum value is 1L milliseconds. onClick: () -> Unit ) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() val pressedListener by rememberUpdatedState(onClick) LaunchedEffect(isPressed) { while (isPressed) { delay(stepDelay.coerceIn(1L, Long.MAX_VALUE)) pressedListener() } } IconButton( modifier = modifier, onClick = onClick, interactionSource = interactionSource ) { Icon( painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage), contentDescription = contentDescription, ) } }
Points clés concernant le code
MomentaryIconButtonutilise ununselectedImage: Int, l'ID de ressource drawable de l'icône lorsque le bouton n'est pas enfoncé, etselectedImage: Int, l'ID de ressource drawable de l'icône lorsque le bouton est enfoncé.- Il utilise un
interactionSourcepour suivre spécifiquement les interactions de type "appui" de l'utilisateur. isPressedest défini sur "true" lorsque l'utilisateur appuie sur le bouton, et sur "false" dans le cas contraire. LorsqueisPressedest défini surtrue,LaunchedEffectentre dans une boucle.- Dans cette boucle, il utilise un
delay(avecstepDelay) pour créer des pauses entre les actions de déclenchement.coerceIngarantit que le délai est d'au moins 1 ms pour éviter les boucles infinies. pressedListenerest appelé après chaque délai dans la boucle. L'action est alors répétée.
- Dans cette boucle, il utilise un
pressedListenerutiliserememberUpdatedStatepour s'assurer que le lambdaonClick(l'action à effectuer) est toujours le plus récent de la dernière composition.- L'image affichée par
Iconchange selon que l'utilisateur appuie ou non sur le bouton.- Si
isPressedest défini sur "true", l'élémentselectedImages'affiche. - Sinon, l'
unselectedImages'affiche.
- Si
Ensuite, utilisez ce MomentaryIconButton dans un exemple. L'extrait de code suivant illustre deux boutons d'icône contrôlant un compteur :
@Preview() @Composable fun MomentaryIconButtonExample() { var pressedCount by remember { mutableIntStateOf(0) } Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { MomentaryIconButton( unselectedImage = R.drawable.fast_rewind, selectedImage = R.drawable.fast_rewind_filled, stepDelay = 100L, onClick = { pressedCount -= 1 }, contentDescription = "Decrease count button" ) Spacer(modifier = Modifier) Text("advanced by $pressedCount frames") Spacer(modifier = Modifier) MomentaryIconButton( unselectedImage = R.drawable.fast_forward, selectedImage = R.drawable.fast_forward_filled, contentDescription = "Increase count button", stepDelay = 100L, onClick = { pressedCount += 1 } ) } }
Points clés concernant le code
- Le composable
MomentaryIconButtonExampleaffiche unRowcontenant deux instancesMomentaryIconButtonet un composableTextpour créer une UI permettant d'incrémenter et de décrémenter un compteur. - Il conserve une variable d'état modifiable
pressedCountà l'aide derememberetmutableIntStateOf, initialisée à 0. LorsquepressedCountchange, tous les composables qui l'observent (comme le composableText) se recomposent pour refléter la nouvelle valeur. - Le premier
MomentaryIconButtondiminuepressedCountlorsque l'utilisateur clique dessus ou le maintient enfoncé. - Le deuxième
MomentaryIconButtonaugmentepressedCountlorsque l'utilisateur clique dessus ou le maintient enfoncé. - Les deux boutons utilisent un
stepDelayde 100 millisecondes, ce qui signifie que l'actiononClickse répète toutes les 100 ms lorsqu'un bouton est enfoncé.
Résultat
La vidéo suivante montre l'interface utilisateur avec les boutons d'icône et le compteur :