Cette page décrit les bonnes pratiques à suivre pour travailler avec des styles qui assurent la cohérence de votre code, ainsi que les principes que nous avons suivis lors de la conception des API.
À faire
Appliquez les bonnes pratiques suivantes :
À faire : utiliser des styles pour les éléments visuels et des modificateurs pour les comportements
Utilisez l'API Styles pour la configuration visuelle (arrière-plans, marges intérieures, bordures) et réservez les modificateurs pour les comportements tels que la logique de clic, la détection des gestes ou l'accessibilité.
À faire : exposer les paramètres de style dans les systèmes de conception
Pour vos propres composants de système de conception personnalisés, vous devez exposer un objet Style après le paramètre de modificateur.
@Composable fun GradientButton( modifier: Modifier = Modifier, // ✅ DO: for design system components, expose a style modifier to consumers to be able to customize the components style: Style = Style ) { // Consume the style }
À faire : remplacer les paramètres visuels par un style
Envisagez de remplacer les paramètres de vos composables par un seul paramètre Style.
Exemple :
// Before @Composable fun OldButton(background: Color, fontColor: Color) { } // After // ✅ DO: Replace visual-based parameters with a style that includes same properties @Composable fun NewButton(style: Style = Style) { }
À faire : privilégier les styles pour les animations
Utilisez le bloc animate intégré pour appliquer un style basé sur l'état avec des animations afin d'améliorer les performances par rapport aux modificateurs.
À faire : profitez de la règle "La dernière écriture l'emporte"
Profitez du fait que les propriétés style se remplacent plutôt que de s'empiler.
Utilisez-le pour remplacer les bordures ou les arrière-plans des composants par défaut sans avoir besoin de plusieurs paramètres.
À éviter
Les formats suivants sont déconseillés :
Ne pas utiliser de styles pour la logique d'interaction
N'essayez pas de gérer la détection de onClick ou de gestes dans un style. Les styles sont limités aux configurations visuelles basées sur l'état. Ils ne doivent donc pas gérer la logique métier, mais uniquement avoir un visuel différent en fonction de l'état.
À ne pas faire : fournir un style par défaut en tant que paramètre par défaut
Les paramètres de style doivent toujours être déclarés à l'aide de style: Style = Style :
@Composable fun BadButton( modifier: Modifier = Modifier, // ❌ DON'T set a default style here as a parameter style: Style = Style { background(Color.Red) } ) { }
Pour inclure un paramètre "par défaut", fusionnez le style du paramètre entrant avec celui défini par défaut :
@Composable fun GoodButton( modifier: Modifier = Modifier, // ✅ Do: always pass it as a Style, do not pass other defaults style: Style = Style ) { // ... val defaultStyle = Style { background(Color.Red) } // ✅ Do Combine defaults inside with incoming parameter Box(modifier = modifier.styleable(styleState, defaultStyle, style)) { // your logic } }
À éviter : fournir des paramètres de style aux composables basés sur la mise en page
Bien que vous puissiez fournir un style à n'importe quel composable, il n'est pas prévu que les composables basés sur la mise en page ou les composables au niveau de l'écran acceptent un style. Du point de vue du consommateur, l'effet d'un style à ce niveau n'est pas clair. Les styles sont conçus pour les composants, et pas nécessairement pour les mises en page.
À ne pas faire : créer des styles dans Composition
Les CompositionLocals sont lus au moment où le style est défini, et non au moment où il est utilisé. Lorsque le style est réellement utilisé, l'état de CompositionLocal peut avoir changé, ce qui entraîne un style inexact.
// DON'T - Create styles in Composition that access composition locals in this way - this will likely lead to issues when style is used / accessed, as it would not get updated when the value changes. @Composable fun containerStyle(): Style { val background = MaterialTheme.colorScheme.background val onBackground = MaterialTheme.colorScheme.onBackground return Style { background(background) contentColor(onBackground) } } // Do: Instead, Create StyleScope extension functions for your subsystems to access themed composition Locals val StyleScope.colors: JetsnackColors get() = JetsnackTheme.LocalJetsnackTheme.currentValue.colors val StyleScope.typography: androidx.compose.material3.Typography get() = JetsnackTheme.LocalJetsnackTheme.currentValue.typography val StyleScope.shapes: Shapes get() = JetsnackTheme.LocalJetsnackTheme.currentValue.shapes // Access CompositionLocals val button = Style { background(colors.brandSecondary) shape(shapes.small) }
À faire : créer un style pour les modifications de valeurs de sous-système
Par exemple, si vous basculez entre le mode sombre et le mode clair, interrogez les valeurs thématiques existantes (via CompositionLocal) pour modifier Style de manière dynamique :
// Do: Use CompositionLocals or themed values to create a single style val buttonStyle = Style { background(colors.brandSecondary) shape(shapes.small) }
À faire : remplacer des styles entiers lorsque le composant diffère fondamentalement selon les définitions de thème
Vous pouvez remplacer des objets de style entiers au niveau d'un thème s'il s'agit de thèmes fondamentalement différents.
Par exemple, si vous créez une application qui propose différents thèmes par produit/page ou offre, et que de nombreuses propriétés d'un style sont différentes, il est acceptable de remplacer des ensembles entiers de styles au niveau du thème.
// DO Switch out whole styles when many properties differ - if Product A and Product B are two white labelled apps that provide different Themes. val productBThemedButton = Style { shape(shapes.small) background(colors.brandSecondary) // other properties are fundamentally different } val productAThemedButton = Style { shape(shapes.large) background(colors.brand) // other properties are fundamentally different }