Animer l'apparence du texte caractère par caractère
Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
Vous pouvez animer l'apparence du texte, caractère par caractère, pour qu'il ressemble à un effet de saisie en streaming, semblable à celui d'une machine à écrire.
Compatibilité des versions
Cette implémentation nécessite que la version minimale du SDK de votre projet soit définie sur le niveau d'API 21 ou supérieur.
Dépendances
Animer le texte caractère par caractère
Ce code anime le texte caractère par caractère. Il suit un indice pour contrôler la quantité de texte révélée. Le texte affiché est mis à jour de manière dynamique pour n'afficher que les caractères jusqu'à l'index actuel. Enfin, la variable exécute l'animation lorsqu'elle change.
@ComposableprivatefunAnimatedText(){valtext="This text animates as though it is being typed \uD83E\uDDDE\u200D♀\uFE0F \uD83D\uDD10 \uD83D\uDC69\u200D❤\uFE0F\u200D\uD83D\uDC68 \uD83D\uDC74\uD83C\uDFFD"// Use BreakIterator as it correctly iterates over characters regardless of how they are// stored, for example, some emojis are made up of multiple characters.// You don't want to break up an emoji as it animates, so using BreakIterator will ensure// this is correctly handled!valbreakIterator=remember(text){BreakIterator.getCharacterInstance()}// Define how many milliseconds between each character should pause for. This will create the// illusion of an animation, as we delay the job after each character is iterated on.valtypingDelayInMs=50LvarsubstringTextbyremember{mutableStateOf("")}LaunchedEffect(text){// Initial start delay of the typing animationdelay(1000)breakIterator.text=StringCharacterIterator(text)varnextIndex=breakIterator.next()// Iterate over the string, by index boundarywhile(nextIndex!=BreakIterator.DONE){substringText=text.subSequence(0,nextIndex).toString()// Go to the next logical character boundarynextIndex=breakIterator.next()delay(typingDelayInMs)}}Text(substringText)
BreakIterator itère correctement sur les caractères, quelle que soit la façon dont ils sont stockés. Par exemple, les emoji animés sont composés de plusieurs caractères. BreakIterator s'assure qu'ils sont traités comme un seul caractère, afin que l'animation ne soit pas interrompue.
LaunchedEffect démarre une coroutine pour introduire le délai entre les caractères. Vous pouvez remplacer le bloc de code par un écouteur de clic (ou tout autre événement) pour déclencher l'animation.
Le composable Text est à nouveau affiché chaque fois que la valeur de substringText est mise à jour.
Résultats
Figure 1 Texte et emoji animés caractère par caractère
Collections contenant ce guide
Ce guide fait partie de ces collections de guides rapides sélectionnées qui couvrent des objectifs de développement Android plus larges:
Texte à afficher
Le texte est un élément central de n'importe quelle interface utilisateur. Découvrez les différentes façons de présenter du texte dans votre application pour offrir une expérience utilisateur agréable.
Le contenu et les exemples de code de cette page sont soumis aux licences décrites dans la Licence de contenu. Java et OpenJDK sont des marques ou des marques déposées d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/02/06 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 2025/02/06 (UTC)."],[],[],null,["\u003cbr /\u003e\n\nYou can animate, character-by-character, the appearance of text, so it looks\nlike a streaming typing effect, similar to what a typewriter would produce.\n\nVersion compatibility\n\nThis implementation requires that your project minSDK be set to API level 21 or\nhigher.\n\nDependencies\n\nAnimate text character-by-character\n\nThis code animates text character-by-character. It tracks an index to control\nhow much of the text is revealed. The displayed text updates dynamically to show\nonly the characters up to the current index. Finally, the variable runs the\nanimation when it changes.\n\n\n```kotlin\n@Composable\nprivate fun AnimatedText() {\n val text = \"This text animates as though it is being typed \\uD83E\\uDDDE\\u200D♀\\uFE0F \\uD83D\\uDD10 \\uD83D\\uDC69\\u200D❤\\uFE0F\\u200D\\uD83D\\uDC68 \\uD83D\\uDC74\\uD83C\\uDFFD\"\n\n // Use BreakIterator as it correctly iterates over characters regardless of how they are\n // stored, for example, some emojis are made up of multiple characters.\n // You don't want to break up an emoji as it animates, so using BreakIterator will ensure\n // this is correctly handled!\n val breakIterator = remember(text) { BreakIterator.getCharacterInstance() }\n\n // Define how many milliseconds between each character should pause for. This will create the\n // illusion of an animation, as we delay the job after each character is iterated on.\n val typingDelayInMs = 50L\n\n var substringText by remember {\n mutableStateOf(\"\")\n }\n LaunchedEffect(text) {\n // Initial start delay of the typing animation\n delay(1000)\n breakIterator.text = StringCharacterIterator(text)\n\n var nextIndex = breakIterator.next()\n // Iterate over the string, by index boundary\n while (nextIndex != BreakIterator.DONE) {\n substringText = text.subSequence(0, nextIndex).toString()\n // Go to the next logical character boundary\n nextIndex = breakIterator.next()\n delay(typingDelayInMs)\n }\n }\n Text(substringText)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/animations/AnimationSnippets.kt#L939-L970\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- [`BreakIterator`](/reference/android/icu/text/BreakIterator) correctly iterates over characters regardless of how they are stored. For example, animated emojis are made up of multiple characters; `BreakIterator` ensures that they're handled as a single character, so that the animation isn't broken.\n- [`LaunchedEffect`](/reference/kotlin/androidx/compose/runtime/package-summary#LaunchedEffect(kotlin.Any,kotlin.coroutines.SuspendFunction1)) starts a coroutine to introduce the delay between the characters. You can replace the code block with a click listener--or any other event--to trigger animation.\n- The [`Text`](/reference/kotlin/androidx/compose/material/package-summary#Text(kotlin.String,androidx.compose.ui.Modifier,androidx.compose.ui.graphics.Color,androidx.compose.ui.unit.TextUnit,androidx.compose.ui.text.font.FontStyle,androidx.compose.ui.text.font.FontWeight,androidx.compose.ui.text.font.FontFamily,androidx.compose.ui.unit.TextUnit,androidx.compose.ui.text.style.TextDecoration,androidx.compose.ui.text.style.TextAlign,androidx.compose.ui.unit.TextUnit,androidx.compose.ui.text.style.TextOverflow,kotlin.Boolean,kotlin.Int,kotlin.Int,kotlin.Function1,androidx.compose.ui.text.TextStyle)) composable re-renders every time the value of `substringText` is updated.\n\nResults\n\n\u003cbr /\u003e\n\n**Figure 1.** Text and emoji animated character-by-character.\n\n\u003cbr /\u003e\n\nCollections that contain this guide\n\nThis guide is part of these curated Quick Guide collections that cover\nbroader Android development goals: \n\nDisplay text \nText is a central piece of any UI. Find out different ways you can present text in your app to provide a delightful user experience. \n[Quick guide collection](/develop/ui/compose/quick-guides/collections/display-text) \n\nCompose basics (video collection) \nThis series of videos introduces various Compose APIs, quickly showing you what's available and how to use them. \n[Quick guide collection](/develop/ui/compose/quick-guides/collections/compose-basics) \n\nHave questions or feedback \nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]